我有三个我试图运行的数组,我想在一个函数中使用所有三个数组的值.这可能听起来令人困惑,但这就是我所拥有的:
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这运行但我得到的是:( makeUser打印出3个值)
Joe, 18, Male
Joe, 20, Male
Joe, 22, Male
Joe, 18, Female
Joe, 20, Female
Joe, 22, Female ....
Run Code Online (Sandbox Code Playgroud)
等等.
我想要的只是
Joe, 18, Male
Sarah, 20, Female
Chad, 22, Male
Run Code Online (Sandbox Code Playgroud)
这可能吗?任何帮助表示赞赏.
谢谢!
Air*_*ity 21
这是一个非常常见的要求,因此标准库可以满足以下功能zip:*
for (a,b) in zip(seq1, seq2) {
// a and b will be matching pairs from the two sequences
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,截至目前,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)
}
Run Code Online (Sandbox Code Playgroud)
请注意,它只能提供最短的序列,因此如果名称多于年龄或性别,您将只获得匹配的名称.
与使用索引相比,这看起来似乎是一个缺点,这看起来似乎也更复杂,但替代方案的简单性具有欺骗性.请记住如果您使用indices或enumerate与不匹配的数组一起会发生什么- 您将获得一个超出边界断言的数组(或者您必须放入检查逻辑).
zip避免这个问题.它还意味着您可以使用序列而不是集合,以及使用不具有整数索引(不同enumerate)的集合或具有不同索引类型的集合(例如a String和an Array).
*(在当前的测试版中,无论如何 - zip返回一个Zip2对象.在Swift 1.1中,你需要Zip2直接创建版本,因为zip它刚刚被引入)
如果您始终确定数组的长度相等,那么您最好只循环其中一个数组并使用它的索引来引用其他数组:
for (index, name) in enumerate(Name) {
makeUser(name, userAge: Age[index], userGender: Gender[index])
}
Run Code Online (Sandbox Code Playgroud)
但是,我建议将此数据放入字典中,但我认为这只是用于说明观点的示例数据。:)
您可以使用自定义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)")
}
Run Code Online (Sandbox Code Playgroud)
上面的代码打印:
Name: Joe, age: 18, gender: Male
Name: Sarah, age: 20, gender: Female
Name: Chad, age: 22, gender: Male
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2005 次 |
| 最近记录: |