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

前端 未结 4 1984
北海茫月
北海茫月 2020-12-10 00:01

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_mu         


        
4条回答
  •  醉酒成梦
    2020-12-10 00:32

    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(_ 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(_ 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:<))
    

提交回复
热议问题