Vyachaslav Gerchicov
Vyachaslav Gerchicov

Reputation: 2457

Sort array and leave the original order for some elements in objective C/swift?

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

Answers (1)

Alain T.
Alain T.

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

Related Questions