使用条件排序迭代一般类型的Swift Dictionary

时间:2015-02-21 19:53:14

标签: swift dictionary iteration generic-collections

我在Swift中的通用Dictionary集合上有两个版本的循环。我对重构版本不满意,因为它有从dict.keys返回的Array中创建新LazyBidirectionalCollection对象的开销。

另一方面,可能没有真正的额外开销,我也提出太多抗议。第三方面,我很想深入了解这一点,我知道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, {$0 < $1}) {
            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, {$0 < $1}) : Array(dict.keys)
    for k in keys {
        d += "\(k): \(dict[k]!)\n"
    }
    return d
}

2 个答案:

答案 0 :(得分:1)

感谢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) {$0 < $1}) : SequenceOf(dict.keys) {
        printOut += "\(k): \(dict[k]!) "
    }
    return printOut
}

虽然后续问题是,如果我想使用reduce而不是for-loop,但我仍然不想想要创建数组,我该怎么办?在上面的序列上创建一个类型擦除的Collection视图。

无论如何,如果阵列版本同样有效,这可能是更好的表示法:

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

答案 1 :(得分:1)

我打算提出与你更新的答案类似的东西:)。这是一个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("") { $0 + "\($1): \(dict[$1]!) " }
}

我不知道AnySequence是否真的比[{1}}更有效率。