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]]
我正在 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]]