Arrays 如何在同一个for循环中运行三个单独的数组?

Arrays 如何在同一个for循环中运行三个单独的数组?,arrays,swift,Arrays,Swift,我有三个数组要运行,我想在一个函数中使用所有三个数组的值。这听起来可能让人困惑,但我有以下几点: var Name = [Joe, Sarah, Chad] var Age = [18, 20, 22] var Gender = [Male, Female, Male] for name in Name { for age in Age { for gender in Gender {

我有三个数组要运行,我想在一个函数中使用所有三个数组的值。这听起来可能让人困惑,但我有以下几点:

    var Name = [Joe, Sarah, Chad]
    var Age = [18, 20, 22]
    var Gender = [Male, Female, Male]

    for name in Name {
        for age in Age {
            for gender in Gender {   
                makeUser(name, userAge: age, userGender: gender)
            }
        }
    } 
这会运行,但我得到的是:(makeUser打印出3个值)

等等

我只想

Joe, 18, Male
Sarah, 20, Female
Chad, 22, Male
这可能吗?感谢您的帮助


谢谢

见下文。但是,如果这些数组中的任何一个在大小上与其他数组不同,则代码将崩溃

var Name = ["a", "b", "c"]
var Age = [1, 2, 3]
var Gender = ["m", "f", "m"]

for (var i = 0; i<Name.count; i++) {
    var name = Name[i]
    var age = Age[i]
    var gender = Gender[i]
    makeUser(name, userAge: age, userGender: gender)
}
var Name=[“a”、“b”、“c”]
变量年龄=[1,2,3]
变量性别=[“m”、“f”、“m”]

对于(var i=0;i如果您始终确信数组的长度相等,那么您最好只遍历其中一个数组,并使用它的索引引用其他数组:

for (index, name) in enumerate(Name) {
    makeUser(name, userAge: Age[index], userGender: Gender[index])
}

但是,我建议将这些数据输入字典,但我假设这只是示例数据来说明一点。

这是一个非常常见的要求,因此标准库通过一个函数,即
zip,来满足它:*

for (a,b) in zip(seq1, seq2) {
    // a and b will be matching pairs from the two sequences
}
不幸的是,到目前为止,
zip
只做配对,尽管理论上它可能会被重载来做三元组。不过,这没什么大不了的,你可以把它们套起来:

var names = ["Joe", "Sarah", "Chad"]
var ages = [18, 20, 22]
var genders: [Gender] = [.Male, .Female, .Male]

for (name,(age,gender)) in zip(names,zip(ages,genders)) {
    makeUser(name, userAge: age, userGender: gender)
}
请注意,它最多只能提供最短的序列,因此如果名称多于年龄或性别,则只能获得匹配的名称

与使用索引相比,这似乎是一个不利的方面,这也可能看起来更复杂,但另一种方法的简单性是欺骗性的。请记住,如果在不匹配的数组旁边使用
索引
枚举
,将会发生什么情况–您将得到一个数组越界断言(或者必须放入检查逻辑)

zip
可避免此问题。这还意味着您可以使用序列而不是集合,也可以使用没有整数索引的集合(不像
枚举
)或具有不同索引类型的集合(例如
字符串
数组


*(无论如何,在当前的测试版中–
zip
返回一个
Zip2
对象。在Swift 1.1中,您需要直接创建
Zip2
版本,因为
zip
刚刚推出)

您可以将枚举数强制转换为数组,并使用函数方法将结果映射到您想要的结果

var Name = ["a", "b", "c"]
var Age = [1, 2, 3]
var Gender = ["m", "f", "m"]

let results = Array(Name.enumerated())
    .map {($0.element, Age[$0.index], Gender[$0.index])}

下面是一个使用
zip
和3个数组的解决方案(测试它们的长度是否相同):

但也许其中最干净的只是老式的C型:

for i in 0..<names.count {
    let name = names[i]
    let age = ages[i]
    let gender = genders[i]
    makeUser(name, userAge: age, userGender: gender)
}

对于0中的i..您可以使用自定义的
zip3
函数,这并不难编写

struct Zip3Sequence<E1, E2, E3>: Sequence, IteratorProtocol {
    private let _next: () -> (E1, E2, E3)?

    init<S1: Sequence, S2: Sequence, S3: Sequence>(_ s1: S1, _ s2: S2, _ s3: S3) where S1.Element == E1, S2.Element == E2, S3.Element == E3 {
        var it1 = s1.makeIterator()
        var it2 = s2.makeIterator()
        var it3 = s3.makeIterator()
        _next = {
            guard let e1 = it1.next(), let e2 = it2.next(), let e3 = it3.next() else { return nil }
            return (e1, e2, e3)
        }
    }

    mutating func next() -> (E1, E2, E3)? {
        return _next()
    }
}

func zip3<S1: Sequence, S2: Sequence, S3: Sequence>(_ s1: S1, _ s2: S2, _ s3: S3) -> Zip3Sequence<S1.Element, S2.Element, S3.Element> {
    return Zip3Sequence(s1, s2, s3)
}

let names = ["Joe", "Sarah", "Chad"]
let ages = [18, 20, 22]
let genders = ["Male", "Female", "Male"]

for (name, age, gender) in zip3(names, ages, genders) {
    print("Name: \(name), age: \(age), gender: \(gender)")
}

请添加一些与上述答案相同的东西..现在列举
for i in 0..<names.count {
    let name = names[i]
    let age = ages[i]
    let gender = genders[i]
    makeUser(name, userAge: age, userGender: gender)
}
struct Zip3Sequence<E1, E2, E3>: Sequence, IteratorProtocol {
    private let _next: () -> (E1, E2, E3)?

    init<S1: Sequence, S2: Sequence, S3: Sequence>(_ s1: S1, _ s2: S2, _ s3: S3) where S1.Element == E1, S2.Element == E2, S3.Element == E3 {
        var it1 = s1.makeIterator()
        var it2 = s2.makeIterator()
        var it3 = s3.makeIterator()
        _next = {
            guard let e1 = it1.next(), let e2 = it2.next(), let e3 = it3.next() else { return nil }
            return (e1, e2, e3)
        }
    }

    mutating func next() -> (E1, E2, E3)? {
        return _next()
    }
}

func zip3<S1: Sequence, S2: Sequence, S3: Sequence>(_ s1: S1, _ s2: S2, _ s3: S3) -> Zip3Sequence<S1.Element, S2.Element, S3.Element> {
    return Zip3Sequence(s1, s2, s3)
}

let names = ["Joe", "Sarah", "Chad"]
let ages = [18, 20, 22]
let genders = ["Male", "Female", "Male"]

for (name, age, gender) in zip3(names, ages, genders) {
    print("Name: \(name), age: \(age), gender: \(gender)")
}
Name: Joe, age: 18, gender: Male
Name: Sarah, age: 20, gender: Female
Name: Chad, age: 22, gender: Male