我正在创建一个加密货币价格跟踪应用程序,该应用程序具有一个图表来说明过去7天内投资组合的价值。因此,我需要一种在图表上生成数据点的方法。
对于投资组合中的每种加密货币,我有一个NSDecimalNumber
值数组,它们表示过去一周中每小时的加密货币价格。要创建数据点,我需要一种方法来计算每小时价格的整体加权平均值。加权的意思是,总体平均数组应代表当前持有的每种加密货币的数量。
例如,如果我有以下数组:
Cryptocurrency 1 (25% of the overall portfolio value) - [1.2, 8.3, 7.2]
Cryptocurrency 2 (25% of the overall portfolio value) - [3.4, 9.2, 6.3]
Cryptocurrency 3 (50% of the overall portfolio value) - [6.3, 1.1, 5.9]
结果应为:
[4.3, 4.92, 6.33]
计算的结果:
((1.2 * 0.75) + (3.4 * 0.75) + (6.3 * 1.5)) / 3 = 4.3
((8.3 * 0.75) + (9.2 * 0.75) + (1.1 * 1.5)) / 3 = 4.92
((7.2 * 0.75) + (6.3 * 0.75) + (5.9 * 1.5)) / 3 = 6.33
我敢肯定必须使用map
和reduce
来做到这一点,但是我还没有想到任何可能的解决方案。甚至基于循环的答案也将不胜感激,因为我以后可以简化它。
答案 0 :(得分:1)
您可以尝试以下代码:
let weight = [0.25, 0.25, 0.5]// Weights of your crypto, matrix 1*N
let crypto1 = [1.2, 8.3, 7.2]
let crypto2 = [3.4, 9.2, 6.3]
let crypto3 = [6.3, 1.1, 5.9]
let crypto = [crypto1, crypto2, crypto3]// Matrix M*N
var result: [Double] = []
for i in 0..<weight.count {
let aux = crypto.map { $0[i] }
let sum = zip(aux, weight).map { $0 * $1 }.reduce(0,+)
result.append(sum)
}
print("test: \(result)") // print "test: [4.3, 4.925, 6.325]"
希望这会有所帮助。
答案 1 :(得分:0)
如果有人好奇,这就是我根据qtngo的答案得出的结论:
let holdings = cryptocurrencies.flatMap { cryptocurrency -> (cryptocurrency: Cryptocurrency, assetHolding: AssetHolding)? in
guard let assetHolding = portfolio.assetHolding(forCryptocurrency: cryptocurrency) else {
return nil
}
return (cryptocurrency, assetHolding)
}
let sparklineLength = holdings.map { $0.cryptocurrency.marketOverview.sparkline.count }.min() ?? 0
let weights = holdings.flatMap { holding -> NSDecimalNumber in
let quantity = NSDecimalNumber(value: holding.assetHolding.quantity)
let value = holding.cryptocurrency.marketOverview.valuation.value
let totalHoldingValue = value.multiplying(by: quantity)
let totalPortfolioValue = portfolio.totalValue(withCryptocurrencies: cryptocurrencies)
let percentage = totalHoldingValue.dividing(by: totalPortfolioValue)
return percentage
}
var averageSparkline = [NSDecimalNumber]()
for index in 0..<sparklineLength {
let indexSparklineValues = holdings.flatMap { holding -> NSDecimalNumber? in
return holding.cryptocurrency.marketOverview.sparkline[index]
}
let averageSparklineValue = zip(indexSparklineValues, weights).map { $0.multiplying(by: $1) }.reduce(0, +)
averageSparkline.append(averageSparklineValue)
}
它需要整理一下,可能可以简化,但是可以产生我一直在寻找的结果。