鉴于我在Swift中有一个数组,例如[1,2,3,4],方法pairs()会将其转换为元组数组:[(1,2), (2,3), (3,4)].
Given I've got an array in Swift such as [1,2,3,4], a method pairs() will transform it in to the array of tuples: [(1,2), (2,3), (3,4)].
以下是pairs()行为方式的更多示例:
Here are some more examples of how pairs() should behave:
- pairs([])应该返回[],因为它没有成对.
- pairs([1])也应返回[],因为它没有对.
- pairs([1,2])应该是[(1,2)].它只有一对.
- pairs([]) should return [] as it has no pairs.
- pairs([1]) should also return [], as it has no pairs.
- pairs([1,2]) should be [(1,2)]. It has just one pair.
我可以为Array编写代码来执行此操作,但是我想提供pairs()作为Sequence上的扩展,以便它返回其中的Sequence对.这将使其可以在任何序列上使用,并与map,reduce,filter等方法兼容.
I can write code to do this for Array, but I'd like to have pairs() available as an extension on Sequence, so that it returns a Sequence of the pairs. This would make it useable on any sequence, and compatible with methods such as map, reduce, filter, etc.
如何创建这样的Sequence?以及如何编写以这种方式转换任何Sequence的方法,以便可以尽可能灵活地使用它?
How do I go about creating a Sequence like this? And how do I write the method to transform any Sequence in this way so that it can be used as flexibly as possible?
推荐答案如果定义扩展名,则可以使用zip()和dropFirst() 在Collection类型上:
We can use zip() and dropFirst() if we define an extension on the Collection type:
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)更多示例:
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)]
(与我在此答案的第一版中写的不同...) 应用于Sequence时,此方法并不安全,因为它是 不保证序列可以多次遍历 非破坏性地
(Unlike I wrote in the first version of this answer ...) this approach is not safe when applied to a Sequence, because it is not guaranteed that a sequence can be traversed multiple times non-destructively.
这是具有自定义迭代器类型的直接实现 也可以在序列上使用:
Here is a direct implementation with a custom iterator type which works on sequences as well:
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序列转换为相邻对
发布评论