This is a very common requirement so the standard library caters to it with a function, zip
:*
for (a,b) in zip(seq1, seq2) {
// a and b will be matching pairs from the two sequences
}
Unfortunately, as of right now, zip
only does pairs, even though in theory it could be overloaded to do triples. However, it’s not a big deal, you can just nest them:
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)
}
Note, it will only serve up to the shortest sequence, so if there are more names than ages or genders, you’ll only get the matching names.
This might seem like a down side compared to using an index, and this might also seem more complex, but the alternative’s simplicity is deceptive. Bear in mind what would happen if you used indices
or enumerate
alongside arrays that didn’t match – you’d get an array out of bounds assertion (or you’d have to put in checking logic).
zip
avoids this problem. It also means you can use sequences instead of collections, as well as working with collections that don’t have integer indices (unlike enumerate
) or collections that have different index types (e.g. a String
and an Array
).
*(in the current beta, anyway – zip
returns a Zip2
object. In Swift 1.1, you need to create the Zip2
version directly as zip
has only just been introduced)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…