我想加入两个(或更多)序列,然后创建一个元组序列。其中第一个元组将包含每个序列的第一个元素,第二个元组将包含第二个元素,以此类推…下面是一个示例函数,它接受两个数组并创建第三个元组数组。然后,我可以使用此序列来处理map(),filter()和reduce()函数。
我的示例有效,但缺乏很多方法。它不是用于所有序列的数组,当第一个序列用完元素时,它将停止生成元组。我希望nils出现在不能再提供元素的短序列中。它仅适用于两个数组,我希望适用于任意数量的序列,
部分解决方案将有所帮助。我是一名函数编程新手,因此也应赞赏此函数的专有名称。也许它已经在switfz库中,我只是知道它叫什么。我选择“ join”是因为它与SQL“ join”大致相似,后者也可以创建元组(又称为行)
func join<T> (s1: Array<T>, s2: Array<T>) -> Array<(T,T)> { var g1 = s1.generate(); var g2 = s2.generate(); var result:Array<(T,T)> = [] while let e1 = g1.next() { if let e2 = g2.next() { result.append((e1,e2)) } } return result } class Hamming { class func compute(input: String, against: String) -> Int { return join(Array(input),Array(against)).reduce(0){ return ($1.0 != $1.1) ? $0 + 1 : $0 } } } Hamming.compute("abcde","abcdf") // 1
已经有一个名为的函数Zip2:
Zip2
var first = [0,1,2,3] var second = ["zero", "one", "two", "three"] Array(Zip2(first,second)) // (0, "zero"), (1, "one"), (2, "two"), (3, "three")
但是,此函数不使用nil填充,它也使用序列中传递的两个中最短的一个。注意,尽管它不需要两个序列之间的类型匹配,也不需要任何序列,而不仅仅是数组。
这是我自己的Zip2WithNilPadding实现:
struct Zip2WithNilPadding<T: SequenceType,U: SequenceType>: SequenceType { typealias Generator = GeneratorOf<(T.Generator.Element?, U.Generator.Element?)> let first: T let second: U init(_ first: T, _ second: U) { self.first = first self.second = second } func generate() -> Generator { var generator1: T.Generator? = first.generate() var generator2: U.Generator? = second.generate() return GeneratorOf<(T.Generator.Element?, U.Generator.Element?)>() { let element1 = generator1?.next() let element2 = generator2?.next() if element1 == nil && element2 == nil { return nil } else if element1 == nil{ generator1 = nil } else if element2 == nil { generator2 = nil } return (element1, element2) } } } var first = [0,1,2] var second = ["zero", "one", "two", "three", "four"] Array(Zip2WithNilPadding(first, second))
如果您对具体实现有疑问,请告诉我,我将尽力澄清。此实现还应该帮助您创建一个采用序列数组的Zip。不幸的是,在这种情况下,它们都必须是同一类型的序列,因为您不能拥有数量可变的泛型。