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

前端 未结 4 1920
北海茫月
北海茫月 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:16

    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}
    
    0 讨论(0)
  • 2020-12-10 00:24

    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]) })
    
    0 讨论(0)
  • 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<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:<))
    
    0 讨论(0)
  • 2020-12-10 00:41

    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.

    0 讨论(0)
提交回复
热议问题