变更集 3.2.0

变更集 3.2.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2020年2月
SPM支持SPM

Joachim Bondo 维护。



变更集 3.2.0

Changeset

Changeset – 一个非常酷的小项目
Joel Levin

这是尝试实现 Dave DeLong 的文章中概述的解决方案,文章链接为 Dave DeLongEdit distance and edit steps

Changeset 描述了从一个 Equatable 元素的 Collection 到另一个 Collection 所需要的最小编辑。

它主要是为了与 UITableViewUICollectionView 数据源一起使用,通过检测两套数据之间的添加、删除、替换和移动来编写的。但它也可以用来计算两个数据集之间的更一般的变化。

用法

以下代码计算了标准示例的最小编辑,从字符串集合“kitten”到“sitting”。

let changeset = Changeset(source: "kitten", target: "sitting")

print(changeset)
// 'kitten' -> 'sitting':
//     replace with s at offset 0
//     replace with i at offset 4
//     insert g at offset 6

以下断言将会成功:

let edits = [
    Changeset<String>.Edit(operation: .substitution, value: "s", destination: 0),
    Changeset<String>.Edit(operation: .substitution, value: "i", destination: 4),
    Changeset<String>.Edit(operation: .insertion, value: "g", destination: 6),
]
assert(changeset.edits == edits)

如果您不想使用 Changeset 本身(它还会存储源和目标集合),可以直接调用 edits(在此处使用来自 Apple 的 示例数据

let source = ["Arizona", "California", "Delaware", "New Jersey", "Washington"]
let target = ["Alaska", "Arizona", "California", "Georgia", "New Jersey", "Virginia"]
let edits = Changeset.edits(from: source, to: target)

print(edits)
// [insert Alaska at offset 0, replace with Georgia at offset 2, replace with Virginia at offset 4]

注意,Changeset 使用偏移量而不是索引来引用集合中的元素。这主要是因为 Swift 集合不保证使用基于零的整数索引。有关更多详细信息,请参阅 问题 #37

UIKit集成

偏移值可以直接用于在UITableViewbeginUpdates/endUpdates动画块以及UICollectionViewperformBatchUpdates中,其中Changeset遵循Apple指南中批量插入、删除和重新加载行和节的原理

简而言之;首先针对源集合执行所有删除和替换操作,然后,针对所得集合执行插入。移动只是删除后跟插入的操作。

iOS框架中包含两个便捷扩展(一个在UITableView上,一个在UICollectionView上),使动画的表/集合视图更新变得轻而易举。只需像这样调用update

tableView.update(with: changeset.edits)

自定义比较器

默认情况下,Changeset使用==比较元素,但您可以编写自己的比较器,如以下示例所示,其中“a”的出现总会引起变化。

let alwaysChangeA: (Character, Character) -> Bool = {
    if $0 == "a" || $1 == "a" {
        return false
    } else {
        return $0 == $1
    }
}
let changeset = Changeset(source: "ab", target: "ab", comparator: alwaysChangeA)

因此,changeset将包括将“a”替换为另一个“a”的操作。

let expectedEdits: [Changeset<String>.Edit] = [Changeset.Edit(operation: .substitution, value: "a", destination: 0)]
assert(changeset.edits == expectedEdits)

这可以用作当UITableViewUICollectionView中的单元格在变化时不应动画的情况。

测试应用

Xcode项目还包含一个目标,用于说明在应用程序中使用的方法。

Test App

这使用上述扩展根据Changeset的编辑来动画转换。

许可证

此项目可在MIT许可证下获得。
版权所有 © 2015-18, Joachim Bondo。请参阅LICENSE文件。