同时迭代两个数组
同时迭代两个数组
我是Swift的新手。我一直在做Java编程。我有一个需要用Swift编码的场景。
以下代码是用Java编写的。我需要根据以下场景用Swift编码:
// 使用字符串数组 - strArr1 String strArr1[] = {"Some1","Some2"} String strArr2[] = {"Somethingelse1","Somethingelse2"} for( int i=0;i< strArr1.length;i++){ System.out.println(strArr1[i] + " - "+ strArr2[i]); }
我有几个Swift数组
var strArr1: [String] = ["Some1","Some2"]
var strArr2: [String] = ["Somethingelse1","Somethingelse2"]
for i in 0.. println(strArr1[i] + " - " + strArr2[i]) } // 我需要根据索引在单个for循环中循环 请提供基于索引循环的语法帮助。
从上述内容中,我们可以整理出"Iterate over two arrays simultaneously"这个问题出现的原因以及解决方法。
问题的原因是,需要同时遍历两个数组并进行操作,但是普通的遍历方法无法实现这个需求。
解决方法是使用Swift的zip()函数,该函数可以将两个给定的序列(数组)创建为一系列的元组。通过在for循环中使用zip()函数,可以同时遍历两个数组,并对每对元素进行操作。
具体的代码示例如下:
let strArr1 = ["Some1", "Some2"]
let strArr2 = ["Somethingelse1", "Somethingelse2"]
for (e1, e2) in zip(strArr1, strArr2) {
print("\(e1) - \(e2)")
}
上述代码中,zip()函数接受两个数组作为参数,并返回一个包含两个数组中共同元素的元组数组。在for循环中,使用(e1, e2)来接收每对元素,并对其进行操作,这里是打印出每对元素的值。
需要注意的是,zip()函数只会枚举两个数组中的"公共元素",如果两个数组的长度不同,则较长数组的额外元素会被忽略。
在上述内容中还有一些关于zip()函数的讨论,其中提到了一些关于函数的使用限制和版本的问题。但是从我们整理的内容中,可以得出zip()函数可以解决"同时遍历两个数组并进行操作"的需求。
在Swift 5中,可以使用以下4个Playground代码之一来解决您的问题。
#1. 使用zip(_:_:)函数
在最简单的情况下,您可以使用zip(_:_:)创建一个新的序列,该序列是初始数组中元素的对(元组)。
let strArr1 = ["Some1", "Some2", "Some3"]
let strArr2 = ["Somethingelse1", "Somethingelse2"]
let sequence = zip(strArr1, strArr2)
for (el1, el2) in sequence {
print("\(el1) - \(el2)")
}
/*
prints:
Some1 - Somethingelse1
Some2 - Somethingelse2
*/
#2. 使用Array的makeIterator()方法和while循环
使用简单的while循环和迭代器同时循环遍历两个数组也很容易。
let strArr1 = ["Some1", "Some2", "Some3"]
let strArr2 = ["Somethingelse1", "Somethingelse2"]
var iter1 = strArr1.makeIterator()
var iter2 = strArr2.makeIterator()
while let el1 = iter1.next(), let el2 = iter2.next() {
print("\(el1) - \(el2)")
}
/*
prints:
Some1 - Somethingelse1
Some2 - Somethingelse2
*/
#3. 使用符合IteratorProtocol的自定义类型
在某些情况下,您可能希望创建自己的类型,将初始数组的元素配对。通过使您的类型符合IteratorProtocol,可以实现此目的。请注意,通过使您的类型也符合Sequence协议,可以直接在for循环中使用它的实例。
struct TupleIterator: Sequence, IteratorProtocol {
private var firstIterator: IndexingIterator<[String]>
private var secondIterator: IndexingIterator<[String]>
init(firstArray: [String], secondArray: [String]) {
self.firstIterator = firstArray.makeIterator()
self.secondIterator = secondArray.makeIterator()
}
mutating func next() -> (String, String)? {
guard let el1 = firstIterator.next(), let el2 = secondIterator.next() else { return nil }
return (el1, el2)
}
}
let strArr1 = ["Some1", "Some2", "Some3"]
let strArr2 = ["Somethingelse1", "Somethingelse2"]
let tupleSequence = TupleIterator(firstArray: strArr1, secondArray: strArr2)
for (el1, el2) in tupleSequence {
print("\(el1) - \(el2)")
}
/*
prints:
Some1 - Somethingelse1
Some2 - Somethingelse2
*/
#4. 使用AnyIterator
作为前面示例的替代方案,可以使用AnyIterator。以下代码展示了在Array扩展方法中可能的实现:
extension Array {
func pairWithElements(of array: Array) -> AnyIterator<(Element, Element)> {
var iter1 = self.makeIterator()
var iter2 = array.makeIterator()
return AnyIterator({
guard let el1 = iter1.next(), let el2 = iter2.next() else { return nil }
return (el1, el2)
})
}
}
let strArr1 = ["Some1", "Some2", "Some3"]
let strArr2 = ["Somethingelse1", "Somethingelse2"]
let iterator = strArr1.pairWithElements(of: strArr2)
for (el1, el2) in iterator {
print("\(el1) - \(el2)")
}
/*
prints:
Some1 - Somethingelse1
Some2 - Somethingelse2
*/
喜欢zip!以前不知道这个.... 我总是使用计数器来迭代循环... 我和我那些C编码技巧哈哈!
问题的出现原因是我们想要同时遍历两个数组,并且处理它们的元素。然而,我们发现使用zip函数进行遍历时,如果两个数组的大小不一致,它并不能正常工作。解决方法是使用zip函数前,先判断两个数组的大小是否相等,如果不相等,可以通过添加默认值来使它们的大小相等,然后再使用zip函数进行遍历。
下面是修改后的代码:
let array1 = [0,2,4,6]
let array2 = [1,3,5,7]
if array1.count == array2.count {
zip(array1, array2).forEach {
print($0, $1)
}
} else if array1.count < array2.count {
let diff = array2.count - array1.count
let newArray1 = array1 + Array(repeating: 0, count: diff)
zip(newArray1, array2).forEach {
print($0, $1)
}
} else {
let diff = array1.count - array2.count
let newArray2 = array2 + Array(repeating: 0, count: diff)
zip(array1, newArray2).forEach {
print($0, $1)
}
}
这样,无论两个数组的大小是否相等,我们都可以通过zip函数同时遍历它们,并对它们的元素进行处理。