Swift zip 生成器只迭代一侧两次

标签 swift collections standard-library

我在两个元组数组上使用 zip。当我迭代结果时,结果元组仅包含左侧的元组。

有趣的是,Array(zip(...)) 按预期生成了一个集合。我想节省一些周期和内存,并且不想为了循环而生成一个新数组。

let expectation: [(String, UInt)] = [("bar", 0)]
let comparison: [(String, Int)] = [("foo", 0)]

func ==(lhs: [(String, UInt)], rhs: [(String, Int)]) -> Bool {
    if lhs.count != rhs.count {
        return false
    }

    for (l, r) in zip(lhs, rhs) {
        // Looking at `l` and `r` in lldb shows both are the same.
        if l.0 != r.0 || Int(l.1) != r.1 {
            return false
        }
    }

    return true
}

let equals = (expectation == comparison) // true?!?!

这是一种方便的方法,可以将测试替身中的函数调用记录与来自实际测试用例的测试数据进行比较。双记录 (String, UInt),在测试用例中键入元组会产生 (String, Int),所以我想:让我们创建一个简单的相等函数吧!将 UInt 更改为 Int 不会改变任何事情。

怎么样?渲染 zip 对我来说毫无用处(除非你能解释发生了什么)。

最佳答案

无法确定这是一个错误还是我不理解的东西(怀疑是错误但需要更多地尝试)。

但是,同时这里有一个解决方法,它涉及完全解构数据:

let expectation: [(String, UInt)] = [("bar", 0)]
let comparison: [(String, Int)] = [("foo", 1)]

func ==(lhs: [(String, UInt)], rhs: [(String, Int)]) -> Bool {
    if lhs.count != rhs.count {
        return false
    }

    for ((ls, li),(rs,ri)) in zip(lhs, rhs) {
        // Looking at `l` and `r` in lldb shows both are the same.
        if ls != rs || Int(li) != ri {
            return false
        }
    }

    return true
}

let equals = (expectation == comparison) // now returns false

理论上,这应该更容易写成:

equal(expectation, comparison) {
    $0.0 == $1.0 && Int($0.1) == $1.1
}

除了令人恼火的是,采用谓词的equal 函数仍然要求两个序列的元素相同!雷达 17590938。

针对此特定于数组的快速修复可能如下所示:

func equal<T,U>(lhs: [T], rhs: [U], isEquivalent: (T,U)->Bool) -> Bool {
    if lhs.count != rhs.count { return false }
    return !contains(zip(lhs, rhs)) { !isEquivalent($0) }
}
// now the above use of equal will compile and return the correct result

附注您可能想为 UInt 转换添加溢出检查

关于Swift zip 生成器只迭代一侧两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30413020/

相关文章:

swift - 在 Swift 中对继承自 Codable 的类进行子类化导致的崩溃

swift - LLDB 无法检查变量(在 Xcode 中)

html - 使用 Swift 在 iOS 上将带有 HTML 标记的描述转换为 NSAttributedString 时如何使用旧金山字体

ios - 取消选中 Swift4 中的 TableView 所有 TableView 选择

java - java TreeMap什么时候进行排序?

java - 将值从映射转换为集合

c - 使用 strtod strtof atof printf 进行语言环境不变的字符串处理?

Java,阻塞队列

java - 为什么数字类的 valueOf/parse 方法拒绝 Java 7 中的有效数字?

ocaml - Jane Street 的 ‘Base’ 、 ‘Core’ 和 'Core_kernel' 有什么区别?