Ios 删除Swift 3中字典中的重复值

Ios 删除Swift 3中字典中的重复值,ios,dictionary,swift3,Ios,Dictionary,Swift3,嗨,我有一本字典,我只想删除重复的值(及其键),如下所示: var myDict : [Int:String] = [1:"test1", 2:"test2", 3:"test1", 4:"test4"] 期望输出: [1: "test1", 2: "test2", 4: "test4"] 您可以使用此代码 let newDict = myDict.keys.sorted().reduce([Int:String]()) { (res, key) -> [Int:String] in

嗨,我有一本字典,我只想删除重复的值(及其键),如下所示:

var myDict : [Int:String] = [1:"test1", 2:"test2", 3:"test1", 4:"test4"]
期望输出:

[1: "test1", 2: "test2", 4: "test4"]
您可以使用此代码

let newDict = myDict.keys.sorted().reduce([Int:String]()) { (res, key) -> [Int:String] in
    guard let value = myDict[key], !res.values.contains(value) else { return res }
    var res = res
    res[key] = value
    return res
}
请记住,字典没有排序,所以输出可能是这样的



请参阅@Duncan提供的,以获得更快的解决方案。

这是另一种方法

var myDict: [Int:String] = [1:"test1", 2:"test2", 3:"test1", 4:"test4"]

var result: [Int:String] = [:]
for (key, value) in myDict {
    if !result.values.contains(value) {
        result[key] = value
    }
}

print(result)
var myDict : [Int:String] = [1:"test1", 2:"test1", 3:"test1", 4:"test4", 5:"test4"]

var newDict:[Int: String] = [:]

for (key, value) in myDict {
    print(key, value)

    let keys = myDict.filter {
        return $0.1.contains(value)
        }.map {
            return $0.0
    }

    if keys.first == key {
        newDict[key] = value
    }
}

print(newDict)

在我看来,所有其他答案的性能都是O(n^2)

以下是一个应在O(n)时间内运行的解决方案:

var sourceDict=[1:“test1”、2:“test2”、3:“test1”、4:“test4”]
var uniqueValues=Set()
var resultDict=[Int:String](最小容量:sourceDict.count)
//如前所述,字典不存在reserveCapacity()函数
//哈米什在评论中指出。请参阅具有最小容量的初始值设定项,
//上面。这就是你建立一个初始容量的字典的方法。
//结果CT.reserveCapacity(sourceDict.count)
对于sourceDict中的(键、值){
if!uniqueValues.contains(值){
唯一值。插入(值)
ResultDisct[键]=值
}
}

对于小型字典来说,差异是微不足道的,但是如果您有一个包含数百(或数千)个键/值对的字典,那么n^2算法的性能开始变得非常糟糕。。

请记住-如果您正在动态构建字典,如果您已经有了条目,那么最好不要在一开始就添加条目,而不是在以后再添加removing@Russell:是的,我就是这么做的。我刚刚编写了一个测试程序,在一个包含10000个键/值对的字典上运行您的代码和我的版本。您的代码运行约23秒。我的花了约0.021秒,比我的快了1000倍多一点。时间差将随着源词典的大小呈几何级数增加。我在词典中使用100000个条目重新运行了测试,我的代码花费了约0.024秒(比10000个条目多了3000分之一秒),到编写此代码时,上述代码仍在运行,大约10分钟后。据我估计大约需要38分钟。N平方算法对于大型数据集来说是非常糟糕的。我在骑自行车的时候让100000个入口测试运行。这个答案中的代码运行时间为49.9分钟,而我的版本为0.024秒。感谢@Duncan C的评论,我实际上使用的是一个小字典,所以算法的复杂性对我来说并不重要。但我在使用大型词典时会注意到这一点!干杯。刚刚尝试了您的解决方案,我得到一个类型为“[Int:String]”的错误值没有成员“reserveCapacity”,可能初始值设定项签名已更改为Swift 3中的其他内容。请注意,使用N平方算法,所需时间开始急剧增长,大约为30项。它不需要一个非常大的数据集就可以让人注意到它。查看我对Appz答案的最后一条评论。
Dictionary
没有
reserveCapacity(:)
方法(尽管它确实应该有)–你可能想用
init(minimumCapacity:)
初始化器来代替。@Hamish,是的,当我试图实际运行它时,我意识到了这一点,但我懒得编辑我的答案。谢谢你让我保持诚实。
var myDict : [Int:String] = [1:"test1", 2:"test1", 3:"test1", 4:"test4", 5:"test4"]

var newDict:[Int: String] = [:]

for (key, value) in myDict {
    print(key, value)

    let keys = myDict.filter {
        return $0.1.contains(value)
        }.map {
            return $0.0
    }

    if keys.first == key {
        newDict[key] = value
    }
}

print(newDict)
var sourceDict = [1:"test1", 2:"test2", 3:"test1", 4:"test4"]

var uniqueValues = Set<String>()
var resultDict = [Int:String](minimumCapacity: sourceDict.count)

//The reserveCapacity() function doesn't exist for Dictionaries, as pointed
//out by Hamish in the comments. See the initializer with minimumCapacity, 
//above. That's the way you have to set up a dictionary with an initial capacity.
//resultDict.reserveCapacity(sourceDict.count)

for (key, value) in sourceDict {
  if !uniqueValues.contains(value) {
    uniqueValues.insert(value)
    resultDict[key] = value
  }
}