How can I sort multiple arrays based on the sorted order of another array

前端 未结 2 1131
情深已故
情深已故 2020-12-01 23:22

I have multiple arrays, and I want to sort all of them based on the sorted order of one of them, like so:

var myArr = [\"b\", \"a\", \"c\"]
var myArr2 = [\"l         


        
相关标签:
2条回答
  • 2020-12-01 23:32

    You can do this by first sorting an array of the keying array’s indices by the values they index, then generating new arrays based on those sorted indices, using PermutationGenerator:

    let myArr = ["b", "a", "c"]
    let myArr2 = ["letter b", "letter a", "letter c"]
    let myArr3 = ["b is the second letter", "a is the first letter", "c is the third letter"]
    
    func sortByKeyArray(keyArray: [String], valuesArrays: [[String]]) -> [[String]] {
    
        precondition(reduce(valuesArrays, true) { $0.0 && ($0.1.count == keyArray.count)},
            "Arrays all need to be the same length")
    
    
        let permutation = sorted(indices(keyArray)) {
            keyArray[$0] < keyArray[$1]
        }
    
        return valuesArrays.map {
            Array(PermutationGenerator(elements: $0, indices: permutation))
        }
    }
    
    sortByKeyArray(myArr, [myArr2, myArr3])
    // returns [["letter a", "letter b", "letter c"], ["a is the first letter", "b is the second letter", "c is the third letter"]]
    

    If you want to make this generic on any kind of collection (but still returning an array, in the same style as the std lib collection algos):

    func sortByKeyingCollection<C: CollectionType, D: SequenceType 
      where D.Generator.Element == C, 
            C.Index: RandomAccessIndexType, 
            C.Generator.Element: Comparable>
    (key: C, values: D) -> [[C.Generator.Element]] {
    
        let permutation = sorted(indices(key)) {
            key[$0] < key[$1]
        }
    
        return map(values) {
            Array(PermutationGenerator(elements: $0, indices: permutation))
        }
    }
    

    And a version that takes a custom comparator:

    func sortByKeyingCollection<C: CollectionType, D: SequenceType where D.Generator.Element == C, C.Index: RandomAccessIndexType>(key: C, values: D, isOrderedBefore: (C.Generator.Element,C.Generator.Element)->Bool) -> [[C.Generator.Element]] {
    
        let permutation = sorted(indices(key)) {
            isOrderedBefore(key[$0],key[$1])
        }
    
        return map(values) {
            Array(PermutationGenerator(elements: $0, indices: permutation))
        }
    }
    
    
    sortByKeyingCollection(myArr, [myArr2, myArr3], >)
    sortByKeyingCollection(myArr, [myArr2, myArr3], lexicographicalCompare)
    sortByKeyingCollection(myArr, [myArr2, myArr3]) { dropFirst($0) < dropFirst($1) }
    
    0 讨论(0)
  • 2020-12-01 23:35

    From what I understand, you want to order your array alphabetically. If so, you can use one of the example below :

    Example 1

    var anArray1 = ["b","a","d","e","c"]
    
    func alphabeticallyOrder(lt : String, rt: String) -> Bool {
        return lt < rt
    }
    
    anArray1 = sorted(anArray1, alphabeticallyOrder)
    
    println(anArray1) // [a, b, c, d, e]
    

    Example 2

    var anArray2 = ["b","a","d","e","c"]
    
    anArray2 = sorted(anArray2, {$0 < $1})
    
    println(anArray2) // [a, b, c, d, e]
    

    Example 3

    var anArray3 = ["b","a","d","e","c"]
    
    anArray3 = sorted (anArray3 , <)
    
    println(anArray3) // [a, b, c, d, e]
    

    Edit : My bad, you also want to change the other arrays indexes in the process. I'll edit later if required.

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