Слияние словаря в Swift с уникальными ключами - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь суммировать словари с уникальным типом -

   let dict1: [String:Any] = ["type":"steps","value": 100]
   let dict2: [String:Any] = ["type":"cal","value": 200]
   let dict3: [String:Any] = ["type":"cal","value": 300]
   let dict4 : [String:Any] = ["type":"steps","value": 400]
   let dict5 : [String:Any] = ["type":"cal","value": 500]

Я просто ищу результат как -

sum is - [["type":"steps","value": 500],["type":"cal","value": 1000]]

Я прошел https://developer.apple.com/documentation/swift/dictionaryно не нашел то, что мне нужно

Пожалуйста, помогите с этим

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Вы можете сделать это так:

        let dict1: [String:Any] = ["type":"steps","value": 100]
        let dict2: [String:Any] = ["type":"cal","value": 200]
        let dict3: [String:Any] = ["type":"cal","value": 300]
        let dict4 : [String:Any] = ["type":"steps","value": 400]
        let dict5 : [String:Any] = ["type":"cal","value": 500]

        let array = [dict1,dict2,dict3,dict4,dict5]

        let list :[String:[[String:Any]]] = Dictionary(grouping: array, by: {$0["type"] as? String ?? ""})

        let result =  list.map { (key,value) -> [String:Any] in
            let sum = value.reduce(0, {$0 + ($1["value"] as? Int ?? 0)})
            return ["type":key , "value":sum]
        }

        print(result)

OutPut:

[["type": "cal", "value": 1000], ["type": "steps", "value": 500]]
0 голосов
/ 24 мая 2018
func sumDict(arrayOfDict: [[String:Any]]) -> [[String:Any]] {
    var stepVal = 0, calVal = 0
    for dict in arrayOfDict {
        if let typeValue = dict["type"] as? String, typeValue == "steps" {
            if let val = dict["value"] as? Int {
                stepVal += val
            }
        } else if let typeValue = dict["type"] as? String, typeValue == "cal" {
            if let val = dict["value"] as? Int {
                calVal += val
            }
        }
    }

    let resultDic = [["type":"cal","value": calVal],["type":"steps","value": stepVal]]
    return resultDic
}
let dict1: [String:Any] = ["type":"steps","value": 100]
let dict2: [String:Any] = ["type":"cal","value": 200]
let dict3: [String:Any] = ["type":"cal","value": 300]
let dict4: [String:Any] = ["type":"steps","value": 400]
let dict5: [String:Any] = ["type":"cal","value": 500]

let array = [dict1,dict2,dict3,dict4,dict5]

print("sum is - \(sumDict(arrayOfDict: array))")
0 голосов
/ 24 мая 2018

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

let dict1: [String: Any] = ["type":"steps","value": 100]
let dict2: [String: Any] = ["type":"cal","value": 200]
let dict3: [String: Any] = ["type":"cal","value": 300]
let dict4: [String: Any] = ["type":"steps","value": 400]
let dict5: [String: Any] = ["type":"cal","value": 500]

let dicts = [dict1, dict2, dict3, dict4, dict5]

// wrapper class

class Wrapper {

    // keys
    static let typeKey = "type"
    static let valueKey = "value"

    // values
    var type: String
    var value: Int

    // init
    init?(dict: [String: Any]) {
        guard let type = dict[Wrapper.typeKey] as? String, let value = dict[Wrapper.valueKey] as? Int else {
            // dict has to contain value & type keys to be valid
            return nil
        }

        self.type = type
        self.value = value
    }

    // converting back to dictionary
    func toDict() -> [String: Any] {
        return [Wrapper.typeKey: type, Wrapper.valueKey: value]
    }

    // summing
    static func sumWrappers(_ wrappers: [Wrapper]) -> [Wrapper] {
        var result: [Wrapper] = []
        wrappers.forEach { wrapper in
            if let existing = result.first(where: { $0.type == wrapper.type }) {
                // wrapper of this type already exists -> increase the value
                existing.value += wrapper.value
            } else {
                // new type of wrapper -> just add it to the result
                result.append(wrapper)
            }
        }

        return result
     }
}

// usage

let wrappers = dicts.compactMap { Wrapper(dict: $0) } // get valid wrappers
let result = Wrapper.sumWrappers(wrappers) // get sums for all the different types

let resultArray = result.map { $0.toDict() } // contains the final result as array of dictionaries

Результат

[["type": "steps", "value": 500], ["type": "cal", "value": 1000]]

...