首页 > 解决方案 > 在数组中找到正确的路径

问题描述

我有一个不同货币的金额列表,我必须将它们转换为欧元货币。

我还有一组代表各种汇率的对象,但并非所有货币都与欧元有直接汇率。

例子:

EUR - USD - 1.359
USD - EUR - 0.736
CAD - USD - 0.932
USD - CAD - 1.200
NTD - CAD - 0.345

在这个例子中,如果我想从 NTD 转换为 EUR,我必须先做 NTD->CAD,然后是 CAD->USD,最后是 USD->EUR。

步数不是预先确定的,可能需要一个或多个步骤才能达到 EUR。

我怎样才能在 Swift 5 中做到这一点?如果从一种货币到欧元只有一步,我就能做到,但如果有更多,我就会迷路。

编辑添加一些代码。

这是我的模型类中的对象“速率”:

struct Rate: Decodable {
    let curFrom: String
    let curTo: String
    let curRate: String

    enum CodingKeys: String, CodingKey {
        case curFrom = "from"
        case curTo = "to"
        case curRate = "rate"
    }
}

当我认为我可能需要两个以上的步骤才能获得欧元货币时,这就是我正在制作的功能:

func sumTransactions() -> Double {
        var total: Double = 0
        itemTransactions.forEach { (transaction) in
            if transaction.currency == "EUR" {
                if let amount = Double(transaction.amount) {
                    total += amount
                }
            } else {
                let foundRates = rates.filter({$0.curTo == "EUR" && $0.curFrom == transaction.currency})
                if foundRates.count > 0 {
                    if let amount = Double(transaction.amount), let rate = Double(foundRates.first!.curRate) {
                        total += amount * rate
                    }
                } else {
                    let foundAltRates = rates.filter({$0.curFrom == transaction.currency})
                    if foundAltRates.count > 0 {
                        let foundRates = foundAltRates.filter({$0.curTo == "EUR"})
                        if foundRates.count > 0 {
                            //
                        }
                    }
                }
            }
        }
        
        
        
        return total
    }

对象“交易”有两个属性:“金额”和“货币”。最后,我必须汇总所有金额,但以欧元货币计算。

标签: arraysswiftfilter

解决方案


基于可以通过简单地将所有汇率转换为欧元来简化手头问题的想法,我们从 REST 服务中获取汇率,并将汇率统一为欧元

enum Currencies: String {
    case euro = "EUR"
    case usd = "USD"
    ...
}

// * -> EUR
var simplifiedRates: [String: Double] = [Currencies.euro.rawValue: 1.0]
var fetchedRates: Set<Rate> = service.fetchRateSet()


for rate in fetchedRates {
    if rate.curTo == Currencies.euro.rawValue {
        simplifiedRates[rate.curFrom] = rate.curRate
        fetchedRates.remove(rate)
    }
}

while !fetchedRates.isEmpty {
    for rate in fetchedRates {
        if let existingRate = simplifiedRates[rate.curTo] {
            simplifiedRates[rate.curFrom] = existingRate * rate.curRate
            fetchedRates.remove(rate)
        }
    }
}

请注意,由于我们将所有这些点与欧元进行比较,所有其他汇率必须具有可转换为欧元的目标货币。(例如,KRW -> USD 需要 USD -> EUR 才能使 KRW -> EUR 工作)

...
fetchedRates.insert(Rate(curFrom: "USD", curTo: "EUR", curRate: 0.736))
fetchedRates.insert(Rate(curFrom: "CAD", curTo: "USD", curRate: 0.932))
print(simplifiedRates)
> ["USD": 0.736, "CAD": 0.685952, "EUR": 1.0]

然后sumTransactions可以整齐地写成这样

func sumTransactions() -> Double { 
    var total: Double = 0
    for transaction in itemTransactions {
        total += simplifiedRates[transaction.currency] * transaction.amount
    }
    return total
}

推荐阅读