Swift中如何将指定格式的二维数组转换为Point结构体的二维数组
如何将二维数组转换为分组的Point结构数组?
问题描述
我有一个二维数组,每个子数组包含1个日期字符串和若干数值:
let values = [ ["2020-01-01", 1, 3, 2], ["2020-02-01", 10, 30, 20], ["2020-03-01", 100, 300, 200] ]
需要将它转换成按价格列分组的Point结构数组,每个价格列对应一个[Point],最终结构如下:
public struct Point { var date: String var price: Double } let expectedResult: [[Point]] = [ [Point(date: "2020-01-01", price: 1), Point(date: "2020-02-01", price: 10), Point(date: "2020-03-01", price: 100)], [Point(date: "2020-01-01", price: 3), Point(date: "2020-02-01", price: 30), Point(date: "2020-03-01", price: 300)], [Point(date: "2020-01-01", price: 2), Point(date: "2020-02-01", price: 20), Point(date: "2020-03-01", price: 200)] ]
我尝试过map或嵌套for循环,但要么得不到预期结果,要么代码可读性极差,请问该怎么实现?
解决方案:用嵌套高阶函数实现清晰转换
核心思路是按价格列遍历:原数组的每一行第一个元素是日期,后面的每个位置对应一个价格列。我们需要为每个价格列,把所有行的「日期+该列价格」组合成Point,再把这些Point数组收集起来。
基础实现(简洁易读)
struct Point { var date: String var price: Double } let values = [ ["2020-01-01", 1, 3, 2], ["2020-02-01", 10, 30, 20], ["2020-03-01", 100, 300, 200] ] // 先处理空数组的边界情况 guard let firstRow = values.first, firstRow.count > 1 else { let expectedResult: [[Point]] = [] print(expectedResult) return } // 遍历每个价格列的索引(从1开始,跳过第0位的日期) let expectedResult = (1..<firstRow.count).map { columnIndex in // 为当前列,遍历所有行生成Point values.map { row in // 强制转换:如果能保证原数组类型正确,这样写最简洁 let date = row[0] as! String let price = row[columnIndex] as! Double return Point(date: date, price: price) } } // 输出验证 print(expectedResult)
安全版实现(避免类型转换崩溃)
如果原数组可能存在类型不一致的情况,可以用compactMap和可选绑定来保证代码健壮性:
let expectedResult = (1..<firstRow.count).compactMap { columnIndex in // 转换当前列的所有行,过滤掉转换失败的元素 let columnPoints = values.compactMap { row -> Point? in guard let date = row[0] as? String, let price = row[columnIndex] as? Double else { return nil // 类型不匹配时跳过该元素 } return Point(date: date, price: price) } // 过滤掉空的列数组(如果某列所有元素都转换失败) return columnPoints.isEmpty ? nil : columnPoints }
代码可读性说明
- 外层
map负责遍历价格列,每个列索引对应一个最终的[Point]数组; - 内层
map负责遍历每一行,取出当前列的价格和日期生成Point; - 这种嵌套高阶函数的写法比嵌套for循环更简洁,逻辑分层清晰,一眼就能看出是按列处理数据。
内容的提问来源于stack exchange,提问作者Ludyem
相关产品推荐
相关产品推荐

