PlatformDating February 2016

How to sort 1 array in Swift / Xcode and reorder multiple other arrays by the same keys changes

Sorry for the complex wording of the question. My main experience is with PHP and it has a command called array_multisort. The syntax is below:

bool array_multisort ( array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR [, mixed $... ]]] )

It lets you sort 1 array and the reorder multiple other arrays based on the key changes in the original.

Is there an equivalent command in Swift / Xcode 7.2?

I have currently have a set of arrays:

FirstName Age City Country Active

Active is an array of time in seconds that a user has been active within my app. I would like to order that descending or ascending and the other arrays to change to remain consistent.

Answers


Alain T. February 2016

You could create an array of indexes in sorted order and use it as a mapping:

var names = [ "Paul", "John", "David" ]
var ages  = [  35,    42,     27 ]

let newOrder = names.enumerate().sort({$0.1<$1.1}).map({$0.0})

names = newOrder.map({names[$0]})
ages  = newOrder.map({ages[$0]})


Hugo Alonso February 2016

I would go with @AntonBronnikov suggestion, and put all your properties into an struct, making an Array of that particular struct and then sorting it.

This data is clearly related and it's a cleaner approach.


FranMowinckel February 2016

Edit this is valid for 2 arrays:

Adding to @AlainT answer, but using zip:

var names = [ "Paul", "John", "David" ]
var ages  = [  35,    42,     27 ]

let sortedTuple = zip(names, ages).sort { $0.0.0 < $0.1.0 }

Something more generic:

names.enumerate().sort({$0.1<$1.1}).map({ (name: $0.1, age: ages[$0.0]) })


dfri February 2016

I believe AlainT:s solution is to prefer, but to extend the variety of options, below follows a solution mimicking what a zip5 method could let us achive (in case we could use zip for zipping together 5 sequences instead of its limit of 2):

/* example arrays */
var firstName: [String] = ["David", "Paul", "Lisa"]
var age: [Int] = [17, 27, 22]
var city: [String] = ["London", "Rome", "New York"]
var country: [String] = ["England", "Italy", "USA"]
var active: [Int] = [906, 299, 5060]

/* create an array of 5-tuples to hold the members of the arrays above.
   This is an approach somewhat mimicking a 5-tuple zip version.        */
var quinTupleArr : [(String, Int, String, String, Int)] = []
for i in 0..<firstName.count {
    quinTupleArr.append((firstName[i], age[i], city[i], country[i], active[i]))
}

/* sort w.r.t. 'active' tuple member */
quinTupleArr.sort { $0.4 < $1.4 }

/* map back to original arrays */
firstName = quinTupleArr.map {$0.0}
age = quinTupleArr.map {$0.1}
city = quinTupleArr.map {$0.2}
country = quinTupleArr.map {$0.3}
active = quinTupleArr.map {$0.4}

Post Status

Asked in February 2016
Viewed 2,252 times
Voted 7
Answered 4 times

Search




Leave an answer