Swift 4 中如何借助 Map/Reduce 更优雅地实现带索引的操作?
嘿,刚好对Swift里的函数式写法熟得很,这就给你捋清楚怎么用map/reduce优雅实现带索引的功能!
核心思路:用enumerated()绑定索引与元素
Swift的数组有个超实用的enumerated()方法,它会把数组转换成一个包含**索引(offset)和对应元素(element)**的序列,这正是我们需要的——不用手动维护索引变量,直接把索引和元素打包传递给map/reduce处理。
场景1:用map生成带索引的新数组
假设你原本的需求是遍历数组,给每个元素加上它的索引标识(比如把["a","b","c"]转成["0: a", "1: b", "2: c"]),原来的for循环写法可能是这样:
let original = ["a", "b", "c"] var result = [String]() for (index, item) in original.enumerated() { result.append("\(index): \(item)") }
换成map的优雅写法,一行就能搞定:
let original = ["a", "b", "c"] let result = original.enumerated().map { index, item in "\(index): \(item)" } // 甚至可以用 shorthand 参数简化: let result = original.enumerated().map { "\($0.offset): \($0.element)" }
场景2:用reduce累积带索引的计算结果
如果需要基于索引做累积计算(比如计算数组元素乘以对应索引的总和),原来的循环写法可能是:
let numbers = [1, 2, 3, 4] var total = 0 for (index, num) in numbers.enumerated() { total += num * index }
用reduce重构后,代码更简洁且声明式:
let numbers = [1, 2, 3, 4] let total = numbers.enumerated().reduce(0) { accumulator, (index, num) in accumulator + num * index } // 或者用元组属性访问: let total = numbers.enumerated().reduce(0) { $0 + $1.element * $1.offset }
进阶:链式组合多个操作
如果还要结合过滤等操作,直接链式调用就行,比如只保留偶数索引的元素再做转换:
let original = ["a", "b", "c", "d"] let evenIndexItems = original.enumerated() .filter { $0.offset % 2 == 0 } // 筛选偶数索引 .map { $0.element } // 提取元素 // 结果:["a", "c"]
这种写法不仅省去了临时变量,还让逻辑更清晰——每一步操作的意图一目了然,完全符合Swift推崇的函数式编程风格~
内容的提问来源于stack exchange,提问作者Torbjørn Kristoffersen
相关产品推荐
相关产品推荐

