【问题标题】:Sorting Dictionaries containing more complex values in Swift在 Swift 中对包含更复杂值的字典进行排序
【发布时间】:2015-05-05 16:48:17
【问题描述】:

根据here....提供的示例,根据具有简单双精度或整数的字典的值进行键排序工作得非常好。

但是更复杂的字典结构呢?

我有一个包含字典值的字典,每个字典值都由一个双元组数组组成。 (很复杂,我知道....)。 我想根据第二个元组数组的总和对字典值进行排序。 (即所有第二个元组元素形成一个数组,并将该数组相加;然后根据最小值对数组和进行排序)。但是所有这些仍然没有丢失字典键上的信息。请求方法的结果会根据"second-tuple-summed-up-array-results)的排序结果返回一个key数组。

这是我对这个问题的“糟糕”试验: 我尝试使用以下 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(>)

【问题讨论】:

    标签: sorting swift dictionary key


    【解决方案1】:

    这是一个正确实现isOrderedBefore 函数的问题。仅仅传入&gt; 并不会减少它(即使假设有一个用于元组数组的&gt; 实现,它几乎肯定不会进行您正在寻找的求和比较)。

    如果我正确理解您的目标,您想根据元组数组中一个元组条目的总和值对键进行排序吗?

    所以是这样的:

    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
    }
    

    这是非常低效的,因为您要为每次比较对数组求和 - 实际上您可能想要记住它,或者如果您经常这样做,可能会根据不同的数据结构重新考虑问题。

    【讨论】:

    • 非常感谢您在这方面的大力帮助!一般来说,我问自己(有几个数组)如何在这几个数组中的每一个上执行快速数组函数(如 map、filter、reduce 甚至自己的数组函数),然后对函数结果进行排序和仍然从一开始就知道数组编号。这就是我想出使用带有值作为数组的字典的想法的原因。但同样,也许有一种更复杂的方法来执行数组函数、过滤并仍然知道排序结果来自哪个数组键。对此有何建议?
    猜你喜欢
    • 2015-12-18
    • 1970-01-01
    • 2019-01-30
    • 2014-07-28
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多