Вычисление двойных чисел по датам в формате timeIntervalSince1970 из 2 разных словарей - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть 2 словаря:

bought: [Int64: [String:String]] - это когда пользователь купил криптовалюту

читаемый словарь:

2018-12-04 17:41:48
["amount": "5000.0", "symbol": "MOBI"]
2018-12-06 13:52:44
["amount": "1.5", "symbol": "ETH"]
2018-12-06 13:53:47
["amount": "200.0", "symbol": "XRP"]
2018-12-08 12:01:04
["amount": "2.0", "symbol": "ETH"]

оригинальный словарь:

[1543945308:["amount": "5000.0", "symbol": "MOBI"],
1544104364:["amount": "1.5", "symbol": "ETH"],
1544104427:["amount": "200.0", "symbol": "XRP"],
1544270464:["amount": "2.0", "symbol": "ETH"]]

pricesForPreviousDays:[Int64:[String:Double]] - цены криптовалют, взятые после их добавления в купленный

читаемый словарь:

2018-12-04 23:59:59
["MOBI": 0.01481]
2018-12-05 23:59:59 
["MOBI": 0.01243]
2018-12-06 23:59:59 
["MOBI": 0.01179, "XRP": 0.3074, "ETH": 90.43]
2018-12-07 23:59:59 
["MOBI": 0.01114, "XRP": 0.3023, "ETH": 93.61]
2018-12-08 23:59:59 
["MOBI": 0.01125, "XRP": 0.3074, "ETH": 91.44]

оригинальный словарь:

[1543967999:["MOBI": 0.01481],
1544054399:["MOBI": 0.01243],
1544140799:["MOBI": 0.01179, "XRP": 0.3074, "ETH": 90.43],
1544227199:["MOBI": 0.01114, "XRP": 0.3023, "ETH": 93.61],
1544313599:["MOBI": 0.01125, "XRP": 0.3074, "ETH": 91.44]]

Iнужно рассчитать сумму денег, которую пользователь имеет за день.Пример словаря moneyForTheDay[Int64:Double], где Int64 - конец дня (у меня есть Расширение даты, которое получает конец дня), а Double - вся сумма денег в этот день.

Итак, за первый день (2018-12-04) код должен вычислять MOBI amount * MOBI price = 5000 * 0.01481 = ?

На третий день (2018-12-06) пользователь добавил XRP и ETH, поэтому код должен рассчитать MOBI amount * MOBI price + XRP amount * XRP price + ETH amount * ETH price

Внимание: На пятый день (2018-12-08) пользователь купил еще 2 ETH, поэтому код должен получить ETH с 2018-12-06 и автоматически сделать сумму 1.5+2 = 3.5, поэтомуETH сумма для 2018-12-08 должна быть 3,5, и формула такая же MOBI amount * MOBI price + XRP amount * XRP price + ETH amount * ETH price

Я пробовал с:

var moneyForDay:[Int64:Double] = [:]
        for key in pricesForPreviousDays.keys{
            for key2 in bought.keys{
                if(Int64(Date(timeIntervalSince1970: TimeInterval(key2)).startOfDay.timeIntervalSince1970)<key){
                    if(pricesForPreviousDays[key]![bought[key2]!["symbol"]!] != nil){
                        if(moneyForDay[key] == nil){
                            moneyForDay[key] = Double(bought[key2]!["amount"]!)! * Double(pricesForPreviousDays[key]![bought[key2]!["symbol"]!]!)
                        }else{
                            var previousMoney = moneyForDay[key]!
                            previousMoney += Double(bought[key2]!["amount"]!)! * Double(pricesForPreviousDays[key]![bought[key2]!["symbol"]!]!)
                            moneyForDay[key] = previousMoney
                        }
                    }
                }
            }
        }

, но он не рассчитывается должным образом, и я нене знаю почему ...

1 Ответ

0 голосов
/ 16 декабря 2018

Я решил работать с датами в виде простой отформатированной строки для простого сравнения дат.Для этого у меня есть простая служебная функция для преобразования даты int

func parseToDateString(_ intDate: Int64) -> String {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withFullDate]
    let date = Date(timeIntervalSince1970: TimeInterval(intDate))
    return formatter.string(from: date)
}

. Для реальных расчетов я решил сначала создать своего рода цепочку событий, чтобы я знал, какие криптовалюты принадлежат для каждой даты, а затем яциклически перебирайте ключи pricesForPreviousDays в порядке дат и ищите собственные валюты и цены в коллекции цен, чтобы рассчитать дневные значения для каждого дня, в который принадлежит валюта, что косвенно определяется диапазоном дат в массиве цен.

typealias CryptoTuple = (symbol: String, amount: Double)
var cryptosPerDay = [String: [CryptoTuple]]()

var prev = ""
bought.keys.sorted(by: <).forEach( { key in
    let date = parseToDateString(key)
    if let buy = bought[key], let symbol = buy["symbol"], let amountStr = buy["amount"], let amount = Double(amountStr) {
        if prev != date {
            cryptosPerDay[date] = [(symbol, amount)]
            if let old = cryptosPerDay[prev] {
                cryptosPerDay[date]?.append(contentsOf: old)
            }
            prev = date
        } else  {
            cryptosPerDay[date]?.append((symbol, amount))
        }
    }
})

var last = [CryptoTuple]()
pricesForPreviousDays.keys.sorted(by: <).forEach( { intDate in
    let date = parseToDateString(intDate)
    let position = cryptosPerDay[date] ?? last

    var totalPerDay = 0.0
    position.forEach( {
        let symbol = $0.symbol
        let amount = $0.amount

        if let item = pricesForPreviousDays.first(where: { parseToDateString($0.key) == date && $0.value.keys.contains(symbol) }) {
            totalPerDay += amount * item.value[symbol]!
        }
    })
    last = position
    print("\(date) - \(totalPerDay)")
})

Вывод

2018-12-04 - 74,05
2018-12-05 - 62,15
2018-12-06 - 256,07500000000005
2018-12-07- 256,575
2018-12-08 - 437,77

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...