I would like to sort the elements of an array based on a custom array that defines the element order. For example, assume the following array:
let arr = ["second", "first", "second", "fourth", "third", "second"]
I tried to create an Array extension to be able to sort this array by:
let sortedArr = arr.sortBy(orderArray: ["first","second","third","fourth"])
// desired output: ["first", "second", "second", "second", "third", "fourth":
However, the extension does not work correctly:
extension Array {
public func sortBy<T: Comparable>(orderArray: [T]) -> [T]? {
guard self.count > 0,
self.first! as? T != nil else {
return nil
}
let indices = self.map {orderArray.index(of: $0 as! T)! }
return self.sorted { indices[$0] > indices[$1] } // This doesn’t work
}
}
Any ideas?
One problem with your code is that
self.sortedexpects a closure comparing array elements, not indices.Here is a possible solution which also avoids unnecessary type casts and unwrappings (explanations inline):
Example:
To move array elements which are not contained in
orderArrayto the end of the sorted result (but preserve their relative order), modify the code slightly toExample: