.enumerated() 是 Swift 中用于迭代集合(如数组、字典等)时,获取每个元素及其索引的一种方法。通常,当遍历一个数组时,只能得到每个元素的值,而 .enumerated() 会返回一个序列,其中的每一项都是一个包含索引和元素的元组 (index, element)。
语法
let enumeratedSequence = array.enumerated()
返回值
enumerated() 返回一个 EnumeratedSequence,它是一个包含元组的序列。每个元组的格式为:
offset:当前元素的索引(从 0 开始)。
element:当前的元素值。
元组的类型是 (offset: Int, element: Element)。
示例
基本用法
let fruits = ["Apple", "Banana", "Cherry"]
for (index, fruit) in fruits.enumerated() {
print("Index \(index): \(fruit)")
}
输出:
Index 0: Apple
Index 1: Banana
Index 2: Cherry
用于 ForEach
如果要在 SwiftUI 中使用 enumerated() 进行循环,比如显示一个带索引的视图列表,可以这样写:
struct ContentView: View {
let fruits = ["Apple", "Banana", "Cherry"]
var body: some View {
VStack {
ForEach(Array(fruits.enumerated()), id: \.offset) { index, fruit in
Text("Index \(index): \(fruit)")
}
}
}
}
ForEach 通常要求唯一标识符,enumerated() 提供了 offset,可以直接用作唯一标识符。
为什么要使用 enumerated()?
enumerated() 的主要作用是同时获取 元素值 和 索引。通常可以用它来:
1、调试输出:
如果在调试代码时需要知道数组中每个元素的索引和内容,enumerated() 很方便。
2、索引依赖的操作:
在需要用索引执行操作时,enumerated() 是很好的工具。例如:
let numbers = [10, 20, 30]
for (index, number) in numbers.enumerated() {
print("The number at index \(index) is \(number * index)")
}
输出:
The number at index 0 is 0
The number at index 1 is 20
The number at index 2 is 60
注意事项
懒加载:enumerated() 返回的是懒加载的序列(EnumeratedSequence),不会立即分配内存来存储索引和元素的元组,只有在遍历时才会逐步生成。
转为数组:如果需要明确的索引和值(如在 ForEach 中使用),可以用 Array(enumerated()) 将其转为数组。
在 SwiftUI 中的使用
在 ForEach 中使用 .enumerated() 可以同时获取索引和元素,这样就可以精确地定位数组中的某个元素,即使它的值是重复的。例如:
List {
ForEach(Array(currencies.enumerated()), id: \.element) { index, currency in
Text("第 \(index) 个货币: \(currency)")
}
}
在这个例子中,ForEach 会遍历 currencies,同时为每个元素提供其索引 index 和具体的值 currency。这样,可以更准确地执行操作,比如替换、删除等。
实际场景1
假设有一个数组:
let currencies = ["美元", "美元", "英镑", "日元", "港币"]
通常使用 for 循环遍历时,只能得到元素的值:
for currency in currencies {
print(currency)
}
输出:
美元
美元
英镑
日元
港币
但是如果想同时得到每个元素的索引和它的值,可以使用 .enumerated():
for (index, currency) in currencies.enumerated() {
print("索引: \(index), 货币: \(currency)")
}
输出:
索引: 0, 货币: 美元
索引: 1, 货币: 美元
索引: 2, 货币: 英镑
索引: 3, 货币: 日元
索引: 4, 货币: 港币
实现场景2
比如,在开发“汇率仓库”App时,想要实现切换货币的效果。
我设定五种常用货币:
@Published var CommonCurrencies = ["USD","EUR","JPY","GBP","HKD"]
在View视图中,通过左划手势切换对应的货币。但因为默认的ForEach轮询数组只能输出其元素,不能输出索引。
ForEach(exchangeRate.CommonCurrencies, id:\.self) { item in
print(item) // 每个货币
}
这就导致,当我尝试左划手势后,只能传递其内容,没有索引的话,就无法修改CommonCurrencies对应的货币币种。
因此,需要使用enumerated()方法获得含有索引和元素的元组。
ForEach(Array(exchangeRate.CommonCurrencies.enumerated()), id:\.element) { index,item in
print(index)
print(item)
]
这样,我就可以在左划的同时,获取到对应货币的索引值。在替换货币页面中,点击新的货币,然后通过获取到的索引值修改CommonCurrencies数组的内容。
最后,就可以实现enumerated()修改对应的货币币种的功能。