Cómo orderar 1 matriz en Swift / Xcode y reorderar varias otras matrices mediante los mismos cambios de keys.

Perdón por la compleja networkingacción de la pregunta. Mi experiencia principal es con PHP y tiene un command llamado array_multisort. La syntax es la siguiente:

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

Le permite orderar 1 matriz y reorderar varias otras matrices según los cambios de key en el original.

¿Hay un command equivalente en Swift / Xcode 7.2?

Actualmente tengo un set de matrices:

Nombre Edad Ciudad País Activo

Activo es una matriz de time en segundos que un usuario ha estado activo dentro de mi aplicación. Me gustaría orderar que descendente o ascendente y las otras matrices para cambiar para permanecer consistente.

Puede crear una matriz de índices en order orderado y usarla como un mapeo:

 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]}) 

[EDIT] Aquí hay una mejora en la técnica:

Es el mismo enfoque, pero hace la sorting y la asignación en un solo paso. (se puede reasignar a matrices originales o a matrices separadas)

 (firstNames,ages,cities,countries,actives) = {( $0.map{firstNames[$0]}, $0.map{ages[$0]}, $0.map{cities[$0]}, $0.map{countries[$0]}, $0.map{actives[$0]} )} (firstNames.enumerated().sorted{$0.1<$1.1}.map{$0.0}) 

[EDIT2] y una extensión de matriz para que sea aún más fácil de usar si está orderando en su lugar:

 extension Array where Element:Comparable { func ordering(by order:(Element,Element)->Bool) -> [Int] { return self.enumerated().sorted{order($0.1,$1.1)}.map{$0.0} } } extension Array { func reorder<T>(_ otherArray:inout [T]) -> [Element] { otherArray = self.map{otherArray[$0 as! Int]} return self } } firstNames.ordering(by: <) .reorder(&firstNames) .reorder(&ages) .reorder(&cities) .reorder(&countries) .reorder(&actives) 

combinando los dos anteriores:

 extension Array { func reordenetworking<T>(_ otherArray:[T]) -> [T] { return self.map{otherArray[$0 as! Int]} } } (firstNames,ages,cities,countries,actives) = {( $0.reordenetworking(firstNames), $0.reordenetworking(ages), $0.reordenetworking(cities), $0.reordenetworking(countries), $0.reordenetworking(actives) )} (firstNames.ordering(by:<)) 

Me gustaría ir con la sugerencia de @AntonBronnikov, y poner todas sus properties en una estructura, hacer una Array de esa struct particular y luego clasificarla.

Esta información está claramente relacionada y es un enfoque más limpio.

Editar esto es válido para 2 arrays:

Agregando a @AlainT respuesta, pero usando zip :

 var names = [ "Paul", "John", "David" ] var ages = [ 35, 42, 27 ] let sortedTuple = zip(names, ages).sort { $0.0.0 < $0.1.0 } 

Algo más genérico:

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

Creo que la solución de AlainT es preferir, pero para ampliar la variedad de opciones, a continuación se muestra una solución que imita lo que un método zip5 podría permitirnos lograr (en caso de que pudiéramos usar un zip para comprimir 5 secuencias en lugar de su límite de 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 wrt '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}