由于这不是语言内置的,这里有一个与内置zip签名相似的简单函数:
func cartesianProduct<Sequence1, Sequence2>(_ sequence1: Sequence1, _ sequence2: Sequence2) -> [(Sequence1.Element, Sequence2.Element)]
where Sequence1 : Sequence, Sequence2 : Sequence
{
var result: [(Sequence1.Element, Sequence2.Element)] = .init()
sequence1.forEach { value1 in
sequence2.forEach { value2 in
result.append((value1, value2))
}
}
return result
}
print(Array(zip([1, 2, 3], ["a", "b"]))) // [(1, "a"), (2, "b")]
print(cartesianProduct([1, 2, 3], ["a", "b"])) // [(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]
在你的情况下,你可以这样做:
cartesianProduct([1,2,3,4,5], ["one","two","three","four","five"])
.map { "\($0.1) \($0.0)" }
甚至:
cartesianProduct(1...5, ["one","two","three","four","five"])
.map { "\($0.1) \($0.0)" }
两者都会产生序列:
["one 1", "two 1", "three 1", "four 1", "five 1", "one 2", "two 2", "three 2", "four 2", "five 2", ...]
由于这在集合的元素上很常见,因此我还创建了这两个功能扩展:
extension Collection {
/// O(n^2)
func pairElementToEveryOtherElement() -> [(Self.Element, Self.Element)] {
var result = [(Self.Element, Self.Element)]()
for i in indices {
var j = index(after: i)
while j != endIndex {
result.append((self[i], self[j]))
j = index(after: j)
}
}
return result
}
/// O(n)
public func pairElementToNeighbors() -> [(Self.Element, Self.Element)] {
if isEmpty {
return .init()
}
var result: [(Self.Element, Self.Element)] = .init()
var i = startIndex
while index(after: i) != endIndex {
result.append((self[i], self[index(after: i)]))
i = index(after: i)
}
return result
}
}
这些可以像下面这样使用:
let inefficientHasDuplicatesCheck = myCollection
.pairElementToEveryOtherElement()
.contains { $0.0 == $0.1 }