我想迭代任意Swift集合并获取元素及其索引。
基本上可以替代:
for (idx, el) in collection.enumerate() {
print("element at \(idx) is \(el)")
}
但是这给了我真正的通用索引,而不仅仅是从0开始的顺序整数。
当然,该解决方案将成为接受任何类型集合的泛型函数的一部分,否则差异不会非常重要。
有没有比下面的天真循环更好的方法?
var idx = collection.startIndex, endIdx = collection.endIndex
while idx < endIdx {
let el = collection[idx]
print("element at \(idx) is \(el)")
idx = idx.successor()
}
写作似乎容易出错。我知道我可以将代码转换为代码片段,但如果可能的话,我想找到更简洁,更惯用的解决方案。
答案 0 :(得分:1)
对于任何集合,indices
属性返回有效范围
指数。迭代索引和相应的元素
与此同时,您可以使用zip()
:
for (idx, el) in zip(collection.indices, collection) {
print(idx, el)
}
数组切片的示例:
let a = ["a", "b", "c", "d", "e", "f"]
let slice = a[2 ..< 5]
for (idx, el) in zip(slice.indices, slice) {
print("element at \(idx) is \(el)")
}
输出:
element at 2 is c element at 3 is d element at 4 is e
您可以为此目的定义自定义扩展方法 (取自How to enumerate a slice using the original indices?):
// Swift 2:
extension CollectionType {
func indexEnumerate() -> AnySequence<(index: Index, element: Generator.Element)> {
return AnySequence(zip(indices, self))
}
}
// Swift 3:
extension Collection {
func indexEnumerate() -> AnySequence<(Indices.Iterator.Element, Iterator.Element)> {
return AnySequence(zip(indices, self))
}
}
角色视图示例:
let chars = "az".characters
for (idx, el) in chars.indexEnumerate() {
print("element at \(idx) is \(el)")
}
输出:
element at 0 is a element at 1 is element at 3 is element at 7 is z