Arrays 在Swift中,我想;加入;元组序列中的两个序列

Arrays 在Swift中,我想;加入;元组序列中的两个序列,arrays,join,swift,sequence,Arrays,Join,Swift,Sequence,我想连接两个(或更多)序列,然后创建一个元组序列。其中第一个元组将包含每个序列的第一个元素,第二个元组将包含第二个元素,等等。。。下面是一个示例函数,它接受两个数组并创建第三个元组数组。然后我可以使用这个序列处理map()、filter()和reduce()函数 我的例子是可行的,但在很多方面都有所欠缺。它适用于数组而不是所有序列,当第一个序列的元素用完时,它停止生成元组。对于不能再提供元素的短序列,我希望nils在元组中。它只适用于两个数组,我希望它适用于任意数量的序列 部分解决方案会有所帮助

我想连接两个(或更多)序列,然后创建一个元组序列。其中第一个元组将包含每个序列的第一个元素,第二个元组将包含第二个元素,等等。。。下面是一个示例函数,它接受两个数组并创建第三个元组数组。然后我可以使用这个序列处理map()、filter()和reduce()函数

我的例子是可行的,但在很多方面都有所欠缺。它适用于数组而不是所有序列,当第一个序列的元素用完时,它停止生成元组。对于不能再提供元素的短序列,我希望nils在元组中。它只适用于两个数组,我希望它适用于任意数量的序列

部分解决方案会有所帮助。我是一个函数编程新手,所以如果能给这个函数取个合适的名字,我将不胜感激。也许它已经在switfz库中了,我只知道它叫什么。我选择“join”是因为它与SQL“join”大致相似,SQL“join”也构建元组(又称行)

func连接(s1:Array,s2:Array)->Array{
var g1=s1.generate();
var g2=s2.generate();
变量结果:数组=[]
而设e1=g1.next(){
如果让e2=g2.next(){
结果追加((e1,e2))
}
}
返回结果
}
汉明班{
类func compute(输入:String,对照:String)->Int{
返回连接(数组(输入),数组(反对)).reduce(0){return($1.0!=$1.1)$0+1:$0}
}
}
compute(“abcde”,“abcdf”)//1

已经有一个名为
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))
struct Zip2WithNilPadding:SequenceType{
typealias生成器=GeneratorOf
让我们先来看看:T
让我们第二个:U
init(U第一个:T,U第二个:U){
self.first=第一
self.second=秒
}
func generate()->生成器{
var generator1:T.Generator?=first.generate()
var generator2:U.Generator?=second.generate()
返回生成器of(){
设element1=generator1?.next()
设element2=generator2?.next()
如果element1==nil&&element2==nil{
归零
}
如果element1==nil,则为else{
发电机1=零
}
如果element2==nil,则为else{
发电机2=零
}
返回(元素1、元素2)
}
}
}
var first=[0,1,2]
第二个变量=[“零”、“一”、“二”、“三”、“四”]
数组(Zip2WithNilPadding(第一、第二))

如果您对具体实施有任何疑问,请告诉我,我将尽力澄清。这个实现还应该帮助您创建一个接受序列数组的Zip。不幸的是,在这种情况下,它们都必须是相同类型的序列,因为不能有数量可变的泛型。

为什么不直接使用
Zip2

reduce(Zip2("abcde","abcdf"), 0) { (d, c) in return d + (c.0 != c.1 ? 1 : 0) } // 1

语法已更改为
Zip2Sequence


数组(Zip2Sequence(arr,second))

自Swift 3以来,有一个创建Zip2Sequence的免费函数:

let s = ["a", "b", "c"]
let n = [1, 2, 3]
let zipped = zip(s, n)          // Zip2Sequence<[String], [Int]>
let zippedArray = Array(zipped) // [(String, Int)]
让s=[“a”、“b”、“c”]
设n=[1,2,3]
设zipped=zip(s,n)//zip2序列
设zippedaray=Array(压缩)//[(字符串,Int)]

这是drewag答案的Swift 4版本。我在GitHub上将其打包为Swift 4包,并进行了一些测试:

以下是Swift 4中的相关代码:

public struct Zip2WithNilPadding<T: Sequence, U: Sequence>: Sequence {
    public typealias Iterator = AnyIterator<(T.Iterator.Element?, U.Iterator.Element?)>

    public let first: T
    public let second: U

    public init(_ first: T, _ second: U) {
        self.first = first
        self.second = second
    }

    public func makeIterator() -> Iterator {
        var iterator1: T.Iterator? = first.makeIterator()
        var iterator2: U.Iterator? = second.makeIterator()

        return Iterator() {
            let element1 = iterator1?.next()
            let element2 = iterator2?.next()

            if element1 == nil && element2 == nil {
              return nil
            } else {
              return (element1, element2)
            }
        }
    }
}
public结构Zip2WithNilPadding:Sequence{
公共类型别名迭代器=任意迭代器
公共租赁优先:T
第二名:美国
public init(U-first:T,U-second:U){
self.first=第一
self.second=秒
}
public func makeIterator()->Iterator{
var iterator1:T.Iterator?=first.makeIterator()
var iterator2:U.Iterator?=second.makeIterator()
返回迭代器(){
设element1=iterator1?.next()
设element2=iterator2?.next()
如果element1==nil&&element2==nil{
归零
}否则{
返回(元素1、元素2)
}
}
}
}

stackoverflow太棒了。。。回答不到2分钟!!是否有处理不同长度序列的模式?2个以上的序列怎么样?我的计算函数的主要部分是:返回数组(Zip2(输入,反对)).reduce(0){return($1.0!=$1.1)?$0+1:$0}我喜欢它@我用自己的实现更新了答案Zip2WithNilPadding@drewag:创建序列的好例子!似乎可以将生成器简化为
returngenerator(){let e1=generator1.next();let e2=generator2.next();如果e1==nil&&e2==nil{return nil},否则{return(e1,e2)}
@MartinR生成器在第一次返回nil后再次调用时不保证继续返回nil。事实上,这是一种未定义的行为。我在实现过程中经历了所有这些麻烦,以确保在返回nil后不会再次调用“next”。
public struct Zip2WithNilPadding<T: Sequence, U: Sequence>: Sequence {
    public typealias Iterator = AnyIterator<(T.Iterator.Element?, U.Iterator.Element?)>

    public let first: T
    public let second: U

    public init(_ first: T, _ second: U) {
        self.first = first
        self.second = second
    }

    public func makeIterator() -> Iterator {
        var iterator1: T.Iterator? = first.makeIterator()
        var iterator2: U.Iterator? = second.makeIterator()

        return Iterator() {
            let element1 = iterator1?.next()
            let element2 = iterator2?.next()

            if element1 == nil && element2 == nil {
              return nil
            } else {
              return (element1, element2)
            }
        }
    }
}