Recently Swift has a new method called move for Arrays. We can use it to tie in with Swiftui list drag and drop list moves. My challenge is that I don't understand how it works standalone and the docs in Apple are sparse about this. Here's a weird behavior I've noticed when I just play with this function.
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)")
Results are:
after 2 -> 1 ["a", "c", "b", "d"]
after 1 -> 2 ["a", "b", "c", "d"]
after 2 -> 2 ["a", "b", "c", "d"]
I'm super confused about the 1->2 result ... how's that not change the array! It should be the same as the 2->1 shouldn't it?
Please help me understand.
CodePudding user response:
my understanding of the move
operation is:
Moves all the elements at the specified offsets to the specified destination offset, preserving ordering.
The move is to just before destination
, so the results you get are correct.
CodePudding user response:
I spend some time making ASCII art diagrams, so let's not put that time to waste.
Conceptually, I think of it as:
- index points to the actual element
- offset is the number of spaces travelled from the start of the array; essentially pointing at the gap between the elements
Thus, the algorithm is to:
- get the item at specified index
- determine the target offset (based on the array as it stands)
- move that item into that offset
So, with your use cases:
["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 ^
| |
--------
As you can see, nominating an offset that would place the element adjacent to itself would result in no apparent change to the array.