You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:02:32