我在swift中有一个数组,我想从重复值(带有它们的值)中删除重复的单个值,如下所示:
var myArray = [
[
"name": "John",
"age": 21
],
[
"name": "Bob",
"age": 35
],
[
"name": "Nyan",
"age": 20
],
[
"name": "Nyan",
"age": 20
]
]
我使用以下代码删除重复值
for i in 0...myArray.count - 1{
if(myArray[i]["name"] as! String == "Nyan"){
print(myArray.remove(at: i))
}
}
print(myArray)
这不会减少myArray.count并给出致命错误:索引超出范围
期望的输出:
[
"name": "John",
"age": 21
],
[
"name": "Bob",
"age": 35
],
[
"name": "Nyan",
"age": 20
]
答案 0 :(得分:3)
而不是删除我建议创建新数组的项目。
您还需要一个帮助程序数组来收集名称。如果names
数组不包含当前名称,请将该名称添加到数组,并将项目添加到result
let myArray = [
["name": "John","age": 21],
["name": "Bob", "age": 35],
["name": "Nyan", "age": 20],
["name": "Nyan", "age": 20]]
var names = [String]()
var result = [[String:Any]]()
for item in myArray {
let name = item["name"] as! String
if !names.contains(name) {
names.append(name)
result.append(item)
}
}
print(result)
而且 - 只是为了好玩 - 使用符合Hashable
的结构的解决方案。
从数组中创建Set
(使项目唯一),然后从集合中创建一个数组。
struct Person : Hashable { let name : String; let age : Int }
let myArray = [Person(name: "John", age: 21), Person(name: "Bob", age: 35), Person(name: "Nyan", age: 20), Person(name: "Nyan", age: 20)]
let result = Array(Set<Person>(myArray))
print(result)
答案 1 :(得分:1)
请使用过滤器或compactMap而不是For循环:
let array: [[String : Any]] = [["Name":"Alice", "Age":"15"],
["Name":"Bob", "Age":"53"],
["Name":"Cathy", "Age":"12"],
["Name":"Bob", "Age":"83"],
["Name":"Denise", "Age":"88"],
["Name":"Alice", "Age":"44"]]
var set = Set<String>()
let arraySet: [[String : Any]] = array.compactMap {
guard let name = $0["Name"] as? String else {return nil }
return set.insert(name).inserted ? $0 : nil
}
print(arraySet)
答案 2 :(得分:0)
func removeDuplicates(_ arrayOfDicts: [[String: String]]) -> [[String:String]] {
var removeDuplicates = [[String: String]]()
var arrOfDict = [String]()
for dict in arrayOfDicts {
if let name = dict["messageTo"], ! arrOfDict.contains(name) {
removeDuplicates.append(dict)
arrOfDict.append(name)
}
}
return removeDuplicates
}
试试这个!
答案 3 :(得分:0)
当您在迭代数组时将删除数组的元素,该数组将与myArray.count
一起使用而不会更改i
。
let myArray = myArray.filter { element in
if myArray.filter({ $0["name"] == element["name"] }).count == 1 {
return true
} else {
return false
}
}
这会过滤数组,只包含只有1个与名称匹配的元素。
答案 4 :(得分:0)
有一个内置的通用集合类型可以为您执行此操作,它被称为Set。 Sets是一个集合类型,如数组,但只存储唯一值,不对它们进行排序。根据您的使用情况,使用集合替换阵列的使用可能是有益的。但您也可以临时使用集来删除重复值,然后将集转换回数组。但是,集合要求其成员符合Hashable协议。 Hashable协议确定值是否重复。字典在某些方面非常简单,但是不要给编译器足够的信息,告诉他们包含什么来做任何有用的事情。
以下是将您的成员类型更改为符合Hashable的结构,使用集删除重复项,然后将该集转换为数组的示例。
struct Person:Hashable
{
var name:String
var age:Int
}
var myArray:[Person] = [
Person( name:"John", age:21 ),
Person( name:"Bob", age:35 ),
Person( name:"Nyan", age:20 ),
Person( name:"Nyan", age:20 ),
]
let mySet = Set<Person>( myArray )
myArray = Array( mySet )