8 Replies
Latest reply on Jan 8, 2020 4:20 AM by ShinehahGnolaum  Level 1 (0 points)

If I have an array of objects that I have to reorder according to an array of integers that represent the original position, how would I reorder the array of objects according to the order given by the array of integers? The reordered objects array would logically be a new array.

For example, an array of objects holds [A, B, C, D] and it needs to be rearranged according to an array of integers [2, 1, 0, 3], where the integer 2, for example, refers to object C, which in the objects array is in position 2. In the new order of the objects array, C would be in the first position, because the integer 2 is in the first position in the integers array.

• ###### Re: How to reorder an array of objects?  Level 8 (8,085 points)

zip is very useful here.

```var initialArray = ["A", "B", "C", "D"]
var positions = [2, 1, 0, 3]
var new = Array(zip(initialArray, positions))
print("zipped", new)
new = new.sorted(by: { \$0.1 < \$1.1})
print("sorted", new)
let sortedArray = new.map() { \$0.0}
print("sortedArray", sortedArray)```

zipped [("A", 2), ("B", 1), ("C", 0), ("D", 3)]

sorted [("C", 0), ("B", 1), ("A", 2), ("D", 3)]

sortedArray ["C", "B", "A", "D"]

• ###### Re: How to reorder an array of objects?  Apple Staff (13,025 points)

Sorting is definitely overkill here.  Try this instead:

```let initialArray = ["A", "B", "C", "D"]
let positions = [2, 1, 0, 3]
let reorderedArray = positions.map { i in
initialArray[i]
}
print(reorderedArray)   // ["C", "B", "A", "D"]```

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
`let myEmail = "eskimo" + "1" + "@apple.com"`

• ###### Re: How to reorder an array of objects?  Level 8 (8,085 points)

Brilliant, indeed.

Just need some safety check, in case of error such as position = [2, 0, 1, 4]

```let reorderedArray = positions.map { (i: Int) -> String in
if i >= initialArray.count {
return initialArray[initialArray.count-1]
} else if i < 0 {
return initialArray
} else {
return initialArray[i]
}
}```

(does not crash with sort)

• ###### Re: How to reorder an array of objects?  Level 3 (160 points)

hi,

very nice, guys, and so i'll be adding this nice one-liner extension to Array for one of my projects:

```extension Array {
func subArrayOrdered(byIndexes indexes: [Int]) -> [Element] {
return indexes.filter({ \$0 >= 0 && \$0 < self.count }).map({ self[\$0] })
}
}
```

possible usage:

```let x = ["A","B","C","D","E","F"]
let indexes = [0, 3, 2, 5, -1, 17]
print(x.subArrayOrdered(byIndexes: indexes))
```

the output is

["A", "D", "C", "F"]

this is a little more general solution than the original question requested -- it picks out any sub array of the original array, ordered by specific indexes (while ignoring improper indices, and it even allows you to repeat an index, which can be either a bug or a feature).  if the index set is a permutation of the index range of the array, then you do indeed get a specific rearrangement of the original array.

regards,

DMG

• ###### Re: How to reorder an array of objects?  Level 1 (0 points)

Thank you DelawareMathGuy.

• ###### Re: How to reorder an array of objects?  Apple Staff (13,025 points)

Two things:

• If you’re going to generalise this, you should worry about collections where the start index isn’t zero.  For example, this code crashes:

```let catchphrase = ["H", "e", "l", "l", "o", " ", "C", "r", "u", "e", "l", " ", "W", "o", "r", "l", "d", "!"]
let cruel = catchphrase[6..<11]
let vowelIndexes = [2, 3]
let vowels = vowelIndexes.map { i in
cruel[i]
}```

because `cruel` is of type `ArraySlice`.  That slice has a `startIndex` of 6, making 2 and 3 out of bounds.  For it to work, you’d need to use `cruel[cruel.startIndex + i]` in line 5.

This problem is particularly tricky for types, like `Data`, where the type and the slice type are the same.

• The Swift Evolution folks are currently working on a standard library addition for sets of indices.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
`let myEmail = "eskimo" + "1" + "@apple.com"`

• ###### Re: How to reorder an array of objects?  Level 1 (0 points)

Thank you everyone Claude31 and eskimo!