2017-01-15 1 views
0

以下のデータでは、選択したインデックスを値の密度(値/重量)降順で並べ替える必要があります。均等になると、私は体重、昇順で「等しい」の間でソートしたい。Swift 3:最初のソート値が等しいときに2番目のソートキーを指定する方法は?

let values = [40, 50, 60, 80, 100, 120, 20, 10] 
let weights = [20, 80, 60, 160, 50, 120, 10, 5] 

// Selection array 
let arr2 = [ 0, 1, 1, 0, 1, 0, 0, 1] 

// Get index from selection 
var selectedIndexes = [Int]() 
arr2.enumerated().forEach { (index, element) in 
    if element == 1 { 
     selectedIndexes.append(index) 
    } 
} 

// without any sorting 
print(selectedIndexes) // [1, 2, 4, 7] 

// sort descending by value density 
selectedIndexes.sort(by: { Double(values[$0])/Double(weights[$0]) > Double(values[$1])/Double(weights[$1]) }) 

print(selectedIndexes) // [4, 7, 2, 1] 

インデックス4と7の両方の値の密度は2.0です。 値の密度が等しい場合、どのようにして重みを昇順に並べ替えることができますか? selectedIndexes配列に[7、4、2、1]があります

+0

これらの値を含む構造体またはクラスを作成する必要があります。このような並列配列を持つことは、お尻の本当の痛みです。 – Alexander

答えて

1

このデータを構造体またはクラスにパッケージ化したいと思っています。その後、そのような操作を行うことは本当に簡単になります!

struct Thing { // TODO: Name me 
    let value: Double 
    let weight: Double 
    let selected: Bool 

    var valueDensity: Double { 
     return value/weight 
    } 
} 

extension Thing: Comparable { 
    public static func <(lhs: Thing, rhs: Thing) -> Bool { 
     if lhs.valueDensity != rhs.valueDensity { // first sort by valueDensity 
      return lhs.valueDensity > rhs.valueDensity // descending 
     } 
     return lhs.weight < rhs.weight // break ties in valueDensity with weight 
    } 

    public static func ==(lhs: Thing, rhs: Thing) -> Bool { 
     return lhs.value == rhs.value 
      && lhs.weight == rhs.weight 
      && lhs.selected == rhs.selected 
    } 
} 

let things = [ 
    Thing(value: 40, weight: 20, selected: false), 
    Thing(value: 50, weight: 80, selected: true), 
    Thing(value: 60, weight: 60, selected: true), 
    Thing(value: 80, weight: 160, selected: false), 
    Thing(value: 100, weight: 50, selected: true), 
    Thing(value: 120, weight: 120, selected: false), 
    Thing(value: 20, weight: 10, selected: false), 
    Thing(value: 10, weight: 5, selected: true), 
] 
print("All things:\r\n\(things)\r\n\r\n") 

let selectedThings = things.enumerated().filter{ offset, element in 
    return element.selected 
} 
print("Selected things:\r\n\(selectedThings)\r\n\r\n") 

let sortedThings = selectedThings.sorted{ $0.element < $1.element } 
print("Sorted things: \r\n\(sortedThings)\r\n\r\n") 

let sortedThingIndices = sortedThings.map{ $0.offset } 
print("Sorted Thing indicies: \r\n\(sortedThingIndices)\r\n\r\n") 
関連する問題