swift - 将 Swift 序列转换为相邻对

标签 swift functional-programming sequence

假设我在 Swift 中有一个数组,例如 [1,2,3,4]pairs() 方法会将其转换为数组元组数:[(1,2), (2,3), (3,4)]

以下是 pairs() 应如何表现的更多示例:

  • pairs([]) 应返回 [],因为它没有对。
  • pairs([1]) 还应该返回 [],因为它没有对。
  • pairs([1,2]) 应为 [(1,2)]。它只有一对。

我可以编写代码来为Array执行此操作,但我希望将pairs()用作Sequence的扩展,以便它返回该对的Sequence。这将使其可用于任何序列,并与 mapreducefilter 等方法兼容。

如何创建这样的序列?我该如何编写方法来以这种方式转换任何Sequence,以便它可以尽可能灵活地使用?

最佳答案

如果我们定义扩展,我们可以使用 zip()dropFirst()Collection 类型上:

extension Collection {
    func pairs() -> AnySequence<(Element, Element)> {
        return AnySequence(zip(self, self.dropFirst()))
    }
}

示例:

let array = [1, 2, 3, 4]
for p in array.pairs() {
    print(p)
}

输出:

(1, 2)
(2, 3)
(3, 4)

More examples:

print(Array("abc".pairs()))
// [("a", "b"), ("b", "c")]

print([1, 2, 3, 4, 5].pairs().map(+))
// [3, 5, 7, 9]

print([3, 1, 4, 1, 5, 9, 2].pairs().filter(<))
// [(1, 4), (1, 5), (5, 9)]
<小时/>

(与我在这个答案的第一个版本中写的不同......) 应用于序列时,该方法并不安全,因为它是 不保证一个序列可以被遍历多次 非破坏性。

这是使用自定义迭代器类型的直接实现 它也适用于序列:

struct PairSequence<S: Sequence>: IteratorProtocol, Sequence {
    var it: S.Iterator
    var last: S.Element?

    init(seq: S) {
        it = seq.makeIterator()
        last = it.next()
    }

    mutating func next() -> (S.Element, S.Element)? {
        guard let a = last, let b = it.next() else { return nil }
        last = b
        return (a, b)
    }
}

extension Sequence {
    func pairs() -> PairSequence<Self> {
        return PairSequence(seq: self)
    }
}

示例:

print(Array([1, 2, 3, 4].pairs().pairs()))
// [((1, 2), (2, 3)), ((2, 3), (3, 4))]

关于swift - 将 Swift 序列转换为相邻对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57474431/

相关文章:

ios - 按钮未显示在用 MarkupKit 编写的简单应用程序上,只有一个按钮

arrays - 如何在 Swift 中将 UnsafeArray<CFloat> 转换为 Array<Float>?

java - 泛型实例化和 Lambdas

r - 如何将数据帧转换为可用格式以在 R 中进行序列挖掘?

oracle - oracle中为什么要按顺序使用缓存和顺序?

ios - 在 ARKit 体验中计算旋转 SCNPlane 的 4 个顶点位置

xcode - 获取与 Swift 一起运行的 Phillips Hue 框架 SDK

r - 在 R 中返回自身的函数?

functional-programming - 返回一对 - 语法错误

wsdl - 如何恢复xsd :elements in xsd:sequence wrappers when websphere is upgraded?的原始顺序