根据提供here的示例,根据字典值的简单双打或Ints的键排序工作完全正常....
但是更复杂的字典结构呢?
我有一个字典值的字典,每个字典都包含一个Double-Tuples数组。 (相当复杂,我知道......)。 我想根据Second-Tuple-Array的总和对字典值进行排序。 (即所有第二元组元素形成一个数组,并且对该数组求和;然后根据最小值对数组求和进行排序)。但所有这些仍然没有丢失关于字典密钥的信息。 ask方法的结果应该根据“second-tuple-summed-up-array-results”的排序结果返回一个键数组。
这是我对这个问题的“差”试验: 我尝试使用以下Playground示例(见下文)根据元组数组的第一元组的值对键进行排序。但它还没有表现......
这适用于基本类型:
extension Dictionary {
func keysSortedByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] {
return sorted(self) {
let (lk, lv) = $0
let (rk, rv) = $1
return isOrderedBefore(lv, rv)
}.map { (k,v) in k }
}
}
let dict = ["a":2, "c":1, "b":3]
dict.keysSortedByValue(<) // result array of keys: ["c", "a", "b"]
dict.keysSortedByValue(>) // result array of keys: ["b", "a", "c"]
但在我更复杂的情况下,它不起作用:
var criteria_array1 = [(Double, Double)]()
var criteria_array2 = [Double]()
var criteria_dict1 = [String:[(Double, Double)]]()
var criteria_dict2 = [String:[Double]]()
// Random creation of two dictionaries with a complex value-structure...
// Dictionary1: keys = Strings, values = array of Double-Tuples
// Dictionary2: keys = Strings, values = array of Doubles
for n in 1...5 {
let currentTopoString: String = "topo_\(n)"
for t in 0...14 {
let a: Double = Double(arc4random_uniform(1000))
let b: Double = Double(Double(arc4random_uniform(1000))/1000)
criteria_array1 += [(a, b)]
criteria_array2 += [b]
}
criteria_dict1[currentTopoString] = criteria_array1
criteria_dict2[currentTopoString] = criteria_array2
criteria_array1.removeAll()
criteria_array2.removeAll()
}
// the two following instruction generate compiler errors....
// why ???????????
// How could a complex dictionary-value-structure be applied to a sortingMethod ??
criteria_dict1.keysSortedByFirstTupleValue(>)
criteria_dict2.keysSortedByFirstTupleValue(>)
答案 0 :(得分:1)
这是适当实施isOrderedBefore
功能的问题。只是传递>
不会削减它(即使假设元组数组有>
的实现,它几乎肯定不会进行你正在寻找的总和的比较对)。
如果我正确理解了您的目标,您希望根据元组数组中某个元组条目之和的值对键进行排序?
这样的事情:
criteria_dict1.keysSortedByValue { lhs, rhs in
// if you actually want to sort by sum of first element in tuple,
// change next.1 to next.0
let left_sum = reduce(lhs, 0) { total, next in total + next.1 }
let right_sum = reduce(rhs, 0) { total, next in total + next.1 }
return left_sum > right_sum
}
这是非常低效的,因为你为每次比较总结了数组 - 实际上你可能想要记住它,或者如果你经常这样做,可能会根据不同的数据结构重新思考问题。 / p>