【问题标题】:Swift: Remove repeated Index and create a new dictionary with reversed index and valueSwift:删除重复的索引并创建一个具有反向索引和值的新字典
【发布时间】:2018-04-12 05:32:34
【问题描述】:

我有一个包含两个 Int 的 A:B 的字典,我想创建一个新字典,其中包含 B 作为索引(不重复)和 A 作为值(仅用于重复的 B):

var myDict : [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]

期望的输出:

var newDict: [Int:[Int]] = [2345: [ 12 , 14 ] , 1111: [ 99 , 67] ]

注意:原始字典包含一千多个条目。

【问题讨论】:

  • 你的问题是什么?您有没有尝试过,或者您希望我们为您编写代码?
  • @JoakimDanielson 肯定有人会这样做。 :p
  • 忍不住:/。我自己也遇到过不知道如何处理事情的情况。
  • @Vollan 正确的方法是,至少想出一个解决方案并要求一个有效的解决方案。
  • 现在查看我更新的答案。我迟到了在寻找简短的答案时发布答案。

标签: arrays swift xcode dictionary


【解决方案1】:

您通过枚举第一个字典来循环它,这样您就可以将值切换到新字典中

var newDict: [Int:[Int]] = [:]
let myDict : [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]



     for values in myDict.enumerated() {
            var newValue = newDict[values.element.value] ?? []
            newValue.append(values.element.key)
            newDict[values.element.value] = newValue
        }

     newDict = newDict.filter { (key, value) -> Bool in
             value.count > 1
        }

【讨论】:

  • 添加了一个过滤器来满足您的需求
【解决方案2】:

这是swift的力量:

let newDict = Dictionary(grouping: myDict, by: {$0.value}).filter({$0.value.count > 1}).mapValues({$0.map({$0.key})})
print(newDict)

输出: [1111: [67, 99], 2345: [12, 14]]

【讨论】:

  • 1 行上的所有内容都很流畅,但是会降低可读性:/
  • 不!谁知道groupingmapfilters 的用途谁知道。如果您仔细阅读它,就会清楚它是如何工作的。
  • 我同意使用这些方法很清楚,但使用 all in 1 line 不清楚。
  • 为此,您可以使用另外两个包含每个过滤器结果的变量。我只是想避免 OP 提到的循环Note: the original dictionary contains over a thousand entries. 显然这会比两个循环快。
【解决方案3】:

请使用此代码:

var myDict: [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
let values = myDict.values
let tempValueSet = Set<Int>(values)
let uniqueValues = Array(tempValueSet)
var result = [Int: [Int]]()

for item in uniqueValues {
    result[item] = myDict.allKeys(forValue: item)
}
print(result)

这是Dictionary 分机:

extension Dictionary where Value: Equatable {
    func allKeys(forValue val: Value) -> [Key] {
        return self.filter { $1 == val }.map { $0.0 }
    }
}

期望的输出:

[6778: [199], 1111: [99, 67], 7657: [77], 3345: [132], 2345: [12, 14]]

有关此扩展的更多参考:https://stackoverflow.com/a/27218964/2284065

如果您不想使用扩展,那么您也可以使用此代码:

var myDict: [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
let values = myDict.values
let tempValueSet = Set<Int>(values)
let uniqueValues = Array(tempValueSet)
var result = [Int: [Int]]()

for item in uniqueValues {
    result[item] = (myDict as NSDictionary).allKeys(for: item) as! [Int]
}
print(result)

【讨论】:

  • 是的,结果不是我想要的检查 Vollan 过滤器。不过谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 2015-09-08
  • 1970-01-01
相关资源
最近更新 更多