【发布时间】:2016-05-02 06:02:51
【问题描述】:
给定两个数组,其中一个是旧值集,另一个是新值,我想找到这两个数组的“差异”,这样对原始数组的更新可以表示为:
enum CollectionChange<T: SequenceType> {
case Initial(T)
case Update(T, deletions: [Int], insertions: [Int], modifications: [Int])
}
我正在尝试构建一个更简单的this 版本,其中更改对象是基于对象相等性构建的,而不是像RAC-MutableCollectionProperty 那样的索引(代码是here,这可能是最一段时间以来,我看到了一段复杂的代码;没有文档也无济于事)。
对于这个项目来说,同样重要的是能够以任何粒度级别观察数组的变化。例如,将T 限制为Equatable 的一维数组是一个相对简单的用例。您可以像RAC-MutableCollectionProperty 那样建立某种描述更改的表,检查对象是否相等。然而,一旦你开始使用二维数组并且更深入,它会变得有点棘手,因为你不仅必须区分最低级别的元素,而且还要描述部分级别的删除。在实践中,实际上并不需要超过 2D 数组,但如果有一个无论数组深度如何都可以工作的解决方案,那就太好了。我不一定要寻找解决方案(尽管那太棒了),实际上只是有关如何解决此问题的任何指针和高级解决方案。
我想到的观察多个数组级别的一种方法是编写一个适用于一维数组的 diffing 函数并构造一个如下属性:
let property: MutableCollectionProperty<MutableCollectionProperty<Int>>
属性将检查其泛型类型是否属于它自己的类型。我必须将更改描述更改为更接近
enum Changes<T> {
case Initial(T)
case Update(T, deletions: [NSIndexPath], insertions: [NSIndexPath], modifications: [NSIndexPath])
}
或者类似的东西
enum Changes<T> {
case Initial(T)
case UpdateSections(sections: [T], deletions:[Int], insertions: [Int], modifications: [Int])
case UpdateIndexes(T, deletions: [Int], insertions: [Int], modifications: [Int])
}
这些只是我的初步想法,我愿意接受任何解决方案或建议。
赏金编辑:
赏金将授予能够提供给出以下参数的解决方案的人:
- 设x和y为两个swift数组
-
T: Equatable类型的两个数组 - 两个数组都可以是任意深度
- x 的深度 == y 的深度
可以在变更集描述的地方生成变更集:
- 哪些元素已从 x 中删除 到 y(按索引)
- 哪些元素已插入到 y 中 不在 x 中(按索引)
- 从 x 开始移动了哪些元素 到 y(按索引)
只需在数组的最低级别描述更改(无需担心插入和删除更高的段,尽管您真的会因此获得 300 个代表)但是更改索引必须指明嵌套的索引路径。
例如,如果数组是一个 3d 数组,并且 array[0][5][2] 处的对象被删除,则结果索引更改应该是数组 [0, 5, 2]。该数组描述了一次删除,所有删除的类型都是[[Int]]。
编辑:
我取消了对任何深度的数组的要求。假设它们只是一维数组。
【问题讨论】:
-
对于邮件格式的道歉,我将使用格式正确的邮件更新我的原始帖子。
-
你可能对github.com/jflinter/Dwifft感兴趣
-
我会看看(可能最终会使用它),但我也有兴趣知道如何自己做。
-
不是一个打包的解决方案,但@DaveDeLong 不久前有一些关于这个主题的useful notes。