Swift数组移动函数的行为与预期不同 - 为什么?

14

近期Swift新增了一种名为move的数组方法,我们可以将其与SwiftUI列表拖放功能相结合。我目前遇到的挑战是,我不理解它如何独立使用,而且苹果公司的文档对此有所欠缺。以下是我在玩弄此函数时注意到的一种奇怪行为。

var array = ["a", "b" ,"c", "d"]
print("before \(array)\n")
array = ["a", "b" ,"c", "d"]
array.move(fromOffsets: IndexSet(integer: 2), toOffset: 1)
print("after 2 -> 1 \(array)")
        
array = ["a", "b" ,"c", "d"]
array.move(fromOffsets: IndexSet(integer: 1), toOffset: 2)
print("after 1 -> 2 \(array)")

array = ["a", "b" ,"c", "d"]
array.move(fromOffsets: IndexSet(integer: 2), toOffset: 2)
print("after 2 -> 2 \(array)")

结果为:

after 2 -> 1 ["a", "c", "b", "d"]

after 1 -> 2 ["a", "b", "c", "d"]

after 2 -> 2 ["a", "b", "c", "d"]

我对1->2的结果感到非常困惑... 这不应该改变数组吗! 它应该与2->1相同,不是吗?

请帮我理解。


似乎第一次交换了b和c,符合预期。第二次将它们交换回来,第三次则没有任何操作。你期望的是什么? - lorem ipsum
请参考workingdgo的答案。你可以尝试使用0代替1来证明它是正确的。偏移量可以高达4,而不是3。 - user652038
2
@loremipsum 在进行所有移动操作之前,我将其重置为 a b c d ... 我预期 1->2 和 2->1 的最终结果完全相同。 - Saviz
3个回答

9
我花了一些时间制作ASCII艺术图表,所以让我们不要浪费那些时间。
概念上,我认为它是这样的:
- 索引指向实际元素 - 偏移量是从数组开头开始旅行的空格数;本质上指向元素之间的间隙
因此,算法是:
- 获取指定索引处的项 - 确定目标偏移量(基于当前数组) - 将该项移动到该偏移量中
因此,在您的用例中:
["a", "b", "c", "d"]: moving from index 2 to offset 1: ["a", "c", "b", "d"]

|a|b|c|d| |a|b|c|d|
     v      ^
     |      |
     +------+

["a", "b", "c", "d"]: moving from index 1 to offset 2: ["a", "b", "c", "d"]

|a|b|c|d| |a|b|c|d|
   v          ^
   |          |
   +----------+

["a", "b", "c", "d"]: moving from index 2 to offset 2: ["a", "b", "c", "d"]

|a|b|c|d| |a|b|c|d|
     v        ^
     |        |
     +--------+

如您所见,提名一个将元素放置在自身旁边的偏移量将导致数组没有明显变化。


4

我对move操作的理解是:

将指定偏移量处的所有元素移动到指定目标偏移量,保持排序。

移动的位置是在目标位置之前,因此您得到的结果是正确的。


我认为我理解不足的是toOffset不是newIndex,以及该项移动到“目标之前”。这就解释了。谢谢。 - Saviz
3
为什么苹果不直接引入类似于 move(fromIndex, toIndex) 的方法呢?我们为什么需要使用 IndexSet - Kyrylo Zapylaiev
1
@KyryloZapylaiev 这样你就可以同时移动多个元素。 - Arutyun Enfendzhyan

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接