Swift 映射嵌套字典以交换外键和内键

Swift map nested dictionary to swap outer and inner keys

我正在 swift 中构建一个应用程序,它显示多个图表,其中一个是汇率图表,可以在 UITableView 中按货币代码和日期范围进行过滤。我能够成功地从 https://fixer.io/ 中提取 FX 数据并将该 json 数据转换为以下 swift 结构:

struct FetchedFXRateByDate: Codable {
let success, timeseries: Bool
let startDate, endDate, base: String
let rates: [String: [String: Double]] // [Date: [Currency Code : Amount]]

enum CodingKeys: String, CodingKey {
    case success, timeseries
    case startDate = "start_date"
    case endDate = "end_date"
    case base, rates
}

}

我现在想要的是操纵或'map'/'filter'内部字典'let rates: [String: [String: Double]]',转换字典:

发件人:

[字符串:[字符串:双精度]] // [日期:[货币代码:金额]]

收件人:

[字符串:[字符串:双精度]] // [货币代码:[日期:金额]]

有效交换密钥。这可以通过带有键的 for 循环轻松完成,但我需要一种更有效的方法来完成任务。这样我就可以在下面的界面中绘制图形:

Graph Table View

非常感谢任何帮助!

一种可能的方法是使用 reduce(into:_:):

有样本:

let rates: [String: [String: Double]] = ["2021-11-14": ["CAD": 1.1,
                                                        "USD": 1.0,
                                                        "EUR": 0.9],
                                         "2021-11-15": ["CAD": 1.11,
                                                        "USD": 1.01,
                                                        "EUR": 0.91]]

这应该可以解决问题:

let target = rates.reduce(into: [String: [String: Double]]()) { partialResult, current in
    let date = current.key
    let dayRates = current.value
    dayRates.forEach { aDayRate in
        var currencyRates = partialResult[aDayRate.key, default: [:]]
        currencyRates[date] = aDayRate.value
        partialResult[aDayRate.key] = currencyRates
    }
}

对于逻辑,我们遍历 rates 的每个元素。 对于每个 [CurrencyCode: Amount],我们迭代它们,并将它们设置为 partialResult(在 reduce(into:_:) 的内部循环结束时将是 finalResult,即返回值).

print(rates)print(target) 的输出(我只是将它们格式化以便于阅读):

$> ["2021-11-14": ["CAD": 1.1, "EUR": 0.9, "USD": 1.0], 
    "2021-11-15": ["USD": 1.01, "EUR": 0.91, "CAD": 1.11]]
$> ["EUR": ["2021-11-14": 0.9, "2021-11-15": 0.91], 
    "USD": ["2021-11-15": 1.01, "2021-11-14": 1.0], 
    "CAD": ["2021-11-14": 1.1, "2021-11-15": 1.11]]