【问题标题】:Find the correct path in array在数组中找到正确的路径
【发布时间】:2021-04-14 13:21:55
【问题描述】:

我有一份不同货币的金额列表,我必须将它们换算成欧元。

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

例子:

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。

步数没有预先确定,可能需要一个或多个步骤才能达到欧元。

如何在 Swift 5 中做到这一点?如果从一种货币到欧元只有一步,我可以做到,但如果有更多,我会迷路。

编辑添加一些代码。

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

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
    }

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

【问题讨论】:

  • 你的代码在哪里?请添加 Rate 的定义以及您自己解决此问题的尝试?
  • 如果有不同的方法可以将一种货币转换为另一种货币,那么“正确的路径”是什么?这不是一个 Swift 问题。
  • 您可能对“节点”、“树”以及如何从中查找值感兴趣。但是通过执行多个预操作,您可能会失去一些精度。
  • 这是一个非常经典的图问题。您的节点是货币,它们之间的弧线是您要兑换的两种货币之间的汇率路径。您的汇率就像距离函数一样工作,因此您可以使用深度优先搜索来找到最便宜的汇率。您还可以将图表“压缩”成最小生成树,这样您就可以使用最少的步骤(但不一定是最佳汇率)在任何支持的货币之间进行转换

标签: arrays swift filter


【解决方案1】:

基于可以通过简单地将所有汇率转换为欧元来简化手头问题的想法,我们从 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
}

【讨论】:

  • 如果我做对了,您的解决方案只有在转换需要中间步骤时才有效,例如 USD -> CAD -> EUR(如果我们没有直接的 USD 到 EUR汇率)。问题是我不知道将一种随机货币兑换成欧元需要多少步骤。
  • 由于我们遍历fetchedRates 集直到它为空,任何最终可以转换为欧元的东西都将变平。例如,韩元 -> 加元,加元 -> 日元,日元 -> 美元,美元 -> 欧元将整齐地变平
  • 我会尝试并告诉你。谢谢。
猜你喜欢
  • 2020-10-06
  • 1970-01-01
  • 2014-06-04
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 2012-05-27
  • 2016-07-13
相关资源
最近更新 更多