0

I want to sort one array and "mirror" order changes to another array of the same dimension.

The question is similar to this one but for Swift language: Better way to sort 2 "linked" arrays?

Example:

let arr1 = ["a", "b", "c", "d", "e"]
let arr2 = [1, 5, 9, 2, 3]
... //sort
//result == ["a", "d", "e", "b", c"]

Approximate solution I know:

for i in stride(from 0, to: arr2.count - 1, by: 1) {
  for j in stride(from i + 1, to: arr2.count, by: 1) {
    if arr2[i] > arr2[j] {
      ...//swap arr2[i] and arr2[j]
      ...//swap arr1[i] and arr1[j]
    }
  }
}

But they added a lot of additional possibilities for advanced working with arrays in Swift. So is it possible to simplify this solution with inner Swift features?

Note: arr1 and arr2 are given as separate arrays.

EDITED

Yes. You found the similar questions but their titles are awful and don't reflect the answers their authors need. In other words if you delete/close my question the people may continue to ask it again because it is impossible to find something with existing titles!

Vyachaslav Gerchicov
  • 2,317
  • 3
  • 23
  • 49
  • 4
    The proper solution is to have just one array. Define a `struct` and keep your data together properly. – rmaddy May 02 '18 at 14:59
  • @staticVoidMan yes, they ask the same thing. BUT in the same time they didn't couch their questions clearly (there is another duplicate question inside your link). `sort array based on array` sounds like 2 arrays with an inheritance-like relationship. `2 linked arrays` is clearer because these arrays have no explicit relationships and it will be easier to find with my title - I see you plan to close and delete my question – Vyachaslav Gerchicov May 02 '18 at 15:24
  • There is no plan to delete your question. It will remain closed as a duplicate. This is fine and not negative to you in any way. People doing a search may come across your question due to the better title. They will see the answer here and the link to the duplicate and all of its answers. Win-win for everyone. – rmaddy May 02 '18 at 15:46

1 Answers1

2
  • zip the arrays together
  • sort the new array by array 2
  • map the array to array 1

    let arr1 = ["a", "b", "c", "d", "e"]
    let arr2 = [1, 5, 9, 2, 3]
    
    let result = zip(arr1, arr2) // [("a", 1), ("b", 5), ("c", 9), ("d", 2), ("e", 3)]
                    .sorted(by: {$0.1 < $1.1}) // [("a", 1), ("d", 2), ("e", 3), ("b", 5), ("c", 9)]
                    .map{ $0.0 } // ["a", "d", "e", "b", "c"]
    
vadian
  • 274,689
  • 30
  • 353
  • 361
  • thanks. The only question I have is it possible to fix your code to access to tuples by name, not a number? – Vyachaslav Gerchicov May 02 '18 at 15:39
  • You could use the full syntax where the shorthands `$0 / $1` are represented by parameter labels. Use code completion and press `return` on the closure placeholder. – vadian May 02 '18 at 15:42