Ich habe ein Array in Swift und möchte einen doppelten einzelnen Wert aus doppelten Werten (mit ihrem Wert) wie folgt entfernen:

var myArray = [
        [
            "name": "John",
            "age": 21
        ],
        [
            "name": "Bob",
            "age": 35
        ],
        [
            "name": "Nyan",
            "age": 20
        ],
        [
            "name": "Nyan",
            "age": 20
        ]
    ]

Ich benutze die folgenden Codes, um doppelte Werte zu entfernen

for i in 0...myArray.count - 1{
        if(myArray[i]["name"] as! String == "Nyan"){
                print(myArray.remove(at: i))
        }
}

print(myArray)

Dies reduziert die myArray.count nicht und führt zu einem schwerwiegenden Fehler: Index außerhalb des Bereichs
Gewünschte Ausgabe:

[
    "name": "John",
    "age": 21
],
[
    "name": "Bob",
    "age": 35
],
[
    "name": "Nyan",
    "age": 20
]
1
Nyan Lin Tun 17 Apr. 2018 im 20:18

5 Antworten

Beste Antwort

Anstatt die Elemente zu entfernen, empfehle ich, ein neues Array zu erstellen.

Sie benötigen auch ein Hilfsarray, um die Namen zu sammeln. Fügen Sie vom Array names, das nicht den aktuellen Namen enthält, den Namen zum Array und das Element zum result hinzu

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)

Und - nur zum Spaß - eine Lösung mit einer Struktur, die Hashable entspricht.

Erstellen Sie ein Set aus dem Array (wodurch die Elemente eindeutig werden) und erstellen Sie dann ein Array aus dem 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)
4
vadian 17 Apr. 2018 im 18:08

Bitte verwenden Sie einen Filter oder eine compactMap anstelle der For-Schleife:

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
Jogendar Choudhary 17 Apr. 2018 im 18:07
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
}

Versuche dies!

0
Deepan 17 Apr. 2018 im 17:36

Sie entfernen ein Element des Arrays, während Sie durch das Array iterieren, das mit myArray.count verschraubt wird, ohne i zu ändern.

Sie könnten dies versuchen:

let myArray = myArray.filter { element in
  if myArray.filter({ $0["name"] == element["name"] }).count == 1 {
    return true
  } else {
    return false
  }
}

Dadurch wird das Array so gefiltert, dass nur Elemente enthalten sind, bei denen nur 1 Element mit dem Namen übereinstimmt.

0
Elijah Moreau-Arnott 17 Apr. 2018 im 18:02

Es gibt einen integrierten generischen Sammlungstyp, der dies für Sie erledigt. Er wird als Set bezeichnet. Sets sind wie Arrays ein Sammlungstyp, speichern jedoch nur eindeutige Werte und bestellen nicht Sie. Abhängig von Ihrem Anwendungsfall kann es vorteilhaft sein, die Verwendung von Arrays durch Sets zu ersetzen. Sie können Sets aber auch vorübergehend verwenden, um doppelte Werte zu entfernen und das Set dann wieder in ein Array zu konvertieren. Für Sets müssen ihre Mitglieder jedoch dem Hashable -Protokoll entsprechen. Das Hashable-Protokoll bestimmt, ob die Werte doppelt vorhanden sind. Wörterbücher sind in mancher Hinsicht sehr einfach zu bearbeiten, geben dem Compiler jedoch nicht genügend Informationen darüber, was sie enthalten, um etwas Nützliches zu tun.

Das folgende Beispiel ändert Ihren Elementtyp in eine Struktur, die Hashable entspricht, verwendet eine Menge, um Duplikate zu entfernen, und konvertiert die Menge dann in ein Array.

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 )
0
Chris Hinkle 17 Apr. 2018 im 18:04