使用条件排序遍历通用类型的 Swift 字典

Iterate through a generically-typed Swift Dictionary with conditional sorting

我在 Swift 中的通用 Dictionary 集合上有两个版本的循环。我对重构版本不满意,因为它有从 dict.keys.

返回的 LazyBidirectionalCollection 中创建新 Array 对象的开销

另一方面,可能没有真正的额外开销,我确实抗议太多了。另一方面,我很想深入了解这一点,以至于我知道 a) 无法避免创建数组或 b) 有一种方法,但它可能有其他缺点。

func dump1<Key, Val where Key: Hashable, Key: Comparable>(dict: [Key: Val], sort: Bool = true) -> String {
    var d = ""

    if sort {
        for k in sorted(dict.keys, {[=11=] < }) {
            d += "\(k): \(dict[k]!)\n"
        }
    }
    else {
        for k in dict.keys {
            d += "\(k): \(dict[k]!)\n"
        }
    }
    return d
}


func dump2<Key, Val where Key: Hashable, Key: Comparable>(dict: [Key: Val], sort: Bool = true) -> String {
    var d = ""

    var keys = sort ? sorted(dict.keys, {[=11=] < }) : Array(dict.keys)
    for k in keys {
        d += "\(k): \(dict[k]!)\n"
    }
    return d
}

感谢 AirSpeed 先生 (http://airspeedvelocity.net/2014/07/28/collection-and-sequence-helpers/),键入擦除是我所缺少的:

func dumpIt<Key, Val where Key: Hashable, Key: Comparable>(dict: [Key: Val], sort: Bool = true) -> String {
    var printOut = ""
    for k in sort ? SequenceOf(sorted(dict.keys) {[=10=] < }) : SequenceOf(dict.keys) {
        printOut += "\(k): \(dict[k]!) "
    }
    return printOut
}

尽管后续问题是,如果我想使用 reduce 而不是 for 循环,但我 仍然不想 创建一个数组,如何在上述序列上创建类型擦除的 Collection 视图。

无论如何,如果数组版本同样有效,这可能是更可取的表示法:

func dumpIt2<Key, Val where Key: Hashable, Key: Comparable>(dict: [Key: Val], sort: Bool = true) -> String {
    return (sort ? sorted(dict.keys) {[=11=] < } : Array(dict.keys)).reduce("") { [=11=] + "\(): \(dict[]!) " }
}

我正要提出与您更新后的答案类似的建议 :)。这是一个 Swift 2.0 版本(虽然更简洁的“sort(<)”当然可以在 Swift 1.2 中使用):

func dump<Key, Val where Key: Hashable, Key: Comparable>(dict: [Key: Val], sort: Bool = true) -> String {
    return (sort ? AnySequence(dict.keys.sort(<)) : AnySequence(dict.keys)).reduce("") { [=10=] + "\(): \(dict[]!) " }
}

我不知道 AnySequence 是否真的应该比 Array 更有效。