Reputation: 2457
I need something like the following:
let arr = [...] //array of strings
let resultArr = arr.sort({obj1,obj2 in
if some_condition(obj1, obj2) {
...//return the order of obj1 and obj2 from arr
} else {
return obj1 < obj2
}
})
I saw a lot of questions/answers how to simply sort the array items but no one answers how to store the original order. some_condition
may be any but each array object may be sorted with the original order or with the new one. How to solve this issue?
Example
let arr = ["a", "f", "d", "b", "y", "c", "e"]
//elements "a", "d", "f" conform some_condition
resultArr == ["a", "f", "d", "b", "c", "e", "y"]
Upvotes: 0
Views: 991
Reputation: 42143
If I understand correctly, the elements that meet your condition need to stay exactly in their original positions and the other ones will be reordered within the positions that are not fixed.
What you could do is map the original indexes of the sortable entries to the sorted subset of their values. Then use that pairing to reassign only the array's elements that are eligible to sorting with their respective (reordered) values.
For example:
var arr = ["a", "f", "d", "b", "y", "c", "e"]
let isFixed:(String)->Bool = { ["a","f","d"].contains($0) } // condition for fixed elements
zip(arr.enumerated().filter{!isFixed($1)},arr.filter{!isFixed($0)}.sorted())
.forEach{ arr[$0.0] = $1 }
print(arr) // ["a", "f", "d", "b", "c", "e", "y"]
Upvotes: 1