Swift:将值键重新映射到字典字典中带有字典射线值的键

时间:2021-06-07 21:20:50

标签: swift dictionary functional-programming

鉴于,

let input = [
    "A": ["X": 1, "Y": 2, "Z": 3],
    "B": ["X": 7, "Y": 8, "Z": 9],
]

你是如何生产的,

[
    "X": ["A": 1, "B": 7],
    "Y": ["A": 2, "B": 8],
    "Z": ["A": 3, "B": 9],
]

使用函数式编程?

2 个答案:

答案 0 :(得分:4)

你可以这样做:

let input = ["A": ["X": 1, "Y": 2, "Z": 3], "B": ["X": 7, "Y": 8, "Z": 9]]

let output = input.flatMap { okv in
    okv.value.map { ikv in
        (ikv.key, okv.key, ikv.value)
        }
    }
    .reduce(into: [String:[(String,Int)]]()) { accum, value in
        accum[value.0] = (accum[value.0] ?? []) + [(value.1,value.2)]
    }
    .reduce(into: [String:[String:Int]]()) { accum, value in
        accum[value.key] = value.value.reduce(into: [String:Int]()) {  iaccum, ivalue in
            iaccum[ivalue.0] = ivalue.1
        }
    }

首先将嵌套字典扩展为元组数组 [("X", "A", 1), ("Y", "A", 2), ... ],然后分两个阶段将该中间数组缩减回字典:首先作为数组字典,然后作为字典字典。< /p>

事实上,如果你利用默认的字典值,你可以做得更好:

let result = input.flatMap { okv in
    okv.value.map { ikv in
        (ikv.key, okv.key, ikv.value)
        }
    }
    .reduce(into: [String:[String:Int]]()) { accum,value in
        accum[value.0, default: [String:Int]()][value.1] = value.2
    }

答案 1 :(得分:2)

我想出了类似下面的东西。我发现使用命令式方法比使用函数式编程更容易理解这个问题。

注意-:我没有涉及边缘情况。

class Test{
    var outputDict:[String:[String:Int]] = [:]
    
    func test(){
        let input = ["A": ["X": 1, "Y": 2, "Z": 3], "B": ["X": 7, "Y": 8, "Z": 9]]
        
        for (key,val) in input{
            var newDict:[String:Int] = [:]
            for (key1,val1) in val{
                generateInternalDict(&newDict, val1, key, key1)
            }
        }
        print(outputDict)
    }
    
    func generateInternalDict(_ newDict:inout [String:Int],_ value:Int,_ keyOuter:String,_ keyInner:String){
        if outputDict[keyInner] == nil{
            newDict[keyOuter] = value
            outputDict[keyInner] = newDict
        }else{
            var getDictForKey = outputDict[keyInner]
            getDictForKey![keyOuter] = value
            outputDict[keyInner] = getDictForKey
        }
    }

}

输出-:

<块引用>

["X": ["B": 7, "A": 1], "Z": ["B": 9, "A": 3], "Y": ["B": 8 , "A": 2]]