Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
250 views
in Technique[技术] by (71.8m points)

ios - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

[EDIT] Here's an improvement on the technique :

It's the same approach but does the sorting and assignment in one step. (can be reassigned to original arrays or to separate ones)

(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] and an Array extension to make it even easier to use if you are sorting in place:

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)

combining the previous two:

extension Array
{
   func reordered<T>(_ otherArray:[T]) -> [T] 
   {
      return self.map{otherArray[$0 as! Int]}
   }
}

(firstNames,ages,cities,countries,actives) = 
    {( 
       $0.reordered(firstNames), 
       $0.reordered(ages), 
       $0.reordered(cities),
       $0.reordered(countries), 
       $0.reordered(actives) 
    )} 
    (firstNames.ordering(by:<))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...