Der beste Weg, um doppelte Werte ( NSString
) aus NSMutableArray
Objective-C zu entfernen ?
Ist dies der einfachste und richtige Weg?
uniquearray = [[NSSet setWithArray:yourarray] allObjects];
ios
objective-c
nsmutablearray
Teo Choong Ping
quelle
quelle
Antworten:
Ihr
NSSet
Ansatz ist der beste, wenn Sie sich keine Sorgen um die Reihenfolge der Objekte machen. Wenn Sie sich jedoch keine Sorgen um die Reihenfolge machen, warum speichern Sie sie dann nicht zunächst in einerNSSet
?Ich habe die Antwort unten 2009 geschrieben. Im Jahr 2011 fügte Apple
NSOrderedSet
iOS 5 und Mac OS X 10.7 hinzu. Was früher ein Algorithmus war, besteht jetzt aus zwei Codezeilen:Wenn Sie sich über die Reihenfolge Sorgen machen und iOS 4 oder früher verwenden, durchlaufen Sie eine Kopie des Arrays:
quelle
[NSOrderedSet orderedSetWithArray:array];
Sie einfach. Sie können dann ein Array über zurückholenarray = [orderedSet allObjects];
oder einfachNSOrderedSet
s anstelle von s verwendenNSArray
.[orderedSet allObjects]
mit[orderedSet array]
!NSArray
und sollten normalerweise Temp schaffenNSMutableArray
. In Ihrem Beispiel arbeiten Sie umgekehrtNSSet
Weiß jemand, welche Ansicht am besten geeignet ist, um Duplikate zu entfernen ? Ist diese Methode (mit ) oder der @ Simon Whitaker- Link zu verhindern, bevor Duplikate hinzugefügt werden?Ich weiß, dass dies eine alte Frage ist, aber es gibt eine elegantere Möglichkeit, Duplikate in einem zu entfernen,
NSArray
wenn Sie sich nicht für die Reihenfolge interessieren .Wenn wir Objektoperatoren aus der Schlüsselwertcodierung verwenden , können wir dies tun:
Wie AnthoPak ebenfalls feststellte, ist es möglich, Duplikate basierend auf einer Eigenschaft zu entfernen. Ein Beispiel wäre:
@distinctUnionOfObjects.name
quelle
@distinctUnionOfObjects.property
, um Duplikate nach Eigenschaften eines Arrays benutzerdefinierter Objekte zu entfernen. Zum Beispiel@distinctUnionOfObjects.name
Ja, die Verwendung von NSSet ist ein sinnvoller Ansatz.
Um die Antwort von Jim Puls zu ergänzen, gibt es hier einen alternativen Ansatz zum Entfernen von Duplikaten unter Beibehaltung der Reihenfolge:
Es ist im Wesentlichen der gleiche Ansatz wie bei Jim, kopiert jedoch eindeutige Elemente in ein neues veränderbares Array, anstatt Duplikate aus dem Original zu löschen. Dies macht es etwas speichereffizienter bei einem großen Array mit vielen Duplikaten (es ist nicht erforderlich, eine Kopie des gesamten Arrays zu erstellen) und ist meiner Meinung nach etwas lesbarer.
Beachten Sie, dass in beiden Fällen die Überprüfung, ob ein Element bereits im Zielarray enthalten ist (
containsObject:
in meinem Beispiel oderindexOfObject:inRange:
in Jims), für große Arrays nicht gut skalierbar ist. Diese Überprüfungen werden in O (N) -Zeit ausgeführt. Wenn Sie also die Größe des ursprünglichen Arrays verdoppeln, dauert die Ausführung jeder Überprüfung doppelt so lange. Da Sie die Prüfung für jedes Objekt im Array durchführen, führen Sie auch mehr dieser teureren Prüfungen durch. Der Gesamtalgorithmus (sowohl meiner als auch Jims) läuft in O (N 2 ) -Zeit, was schnell teuer wird, wenn das ursprüngliche Array wächst.Um dies auf O (N) Zeit zu
NSMutableSet
reduzieren, können Sie mit a einen Datensatz von Elementen speichern, die bereits zum neuen Array hinzugefügt wurden, da NSSet-Lookups O (1) und nicht O (N) sind. Mit anderen Worten, die Überprüfung, ob ein Element Mitglied eines NSSet ist, dauert unabhängig von der Anzahl der Elemente in der Gruppe dieselbe Zeit.Code, der diesen Ansatz verwendet, würde ungefähr so aussehen:
Dies scheint jedoch immer noch ein wenig verschwenderisch; Wir generieren immer noch ein neues Array, wenn die Frage klarstellt, dass das ursprüngliche Array veränderbar ist. Daher sollten wir in der Lage sein, es zu entfernen und Speicherplatz zu sparen. Etwas wie das:
UPDATE : Yuri Niyazov wies darauf hin, dass meine letzte Antwort tatsächlich in O (N 2 )
removeObjectAtIndex:
läuft, weil sie wahrscheinlich in O (N) läuft.(Er sagt "wahrscheinlich", weil wir nicht genau wissen, wie es implementiert ist. Eine mögliche Implementierung ist jedoch, dass die Methode nach dem Löschen des Objekts am Index X jedes Element vom Index X + 1 bis zum letzten Objekt im Array durchläuft Wenn dies der Fall ist, ist dies tatsächlich die O (N) -Leistung.)
Also, was tun? Es hängt von der Situation ab. Wenn Sie ein großes Array haben und nur eine kleine Anzahl von Duplikaten erwarten, funktioniert die direkte Deduplizierung einwandfrei und Sie müssen kein doppeltes Array erstellen. Wenn Sie ein Array haben, in dem Sie viele Duplikate erwarten, ist der Aufbau eines separaten, nicht duplizierten Arrays wahrscheinlich der beste Ansatz. Das Mitnehmen hier ist, dass die Big-O-Notation nur die Eigenschaften eines Algorithmus beschreibt und Ihnen nicht definitiv sagt, welche für einen bestimmten Umstand am besten ist.
quelle
Wenn Sie auf iOS 5+ abzielen (was die gesamte iOS-Welt abdeckt), verwenden Sie es am besten
NSOrderedSet
. Es entfernt Duplikate und behält die Reihenfolge IhrerNSArray
.Mach einfach
Sie können es jetzt wieder in ein eindeutiges NSArray konvertieren
Oder verwenden Sie einfach das orderSet, da es die gleichen Methoden wie ein NSArray
objectAtIndex:
hatfirstObject
und so weiter.Ein Mitgliedschafts-Check mit
contains
ist auf dem noch schnellerNSOrderedSet
als auf einemNSArray
Weitere Informationen finden Sie in der NSOrderedSet-Referenz
quelle
Verfügbar in OS X 10.7 und höher.
Wenn Sie sich Sorgen um die Bestellung machen, ist dies der richtige Weg
Hier ist der Code zum Entfernen doppelter Werte aus NSArray in der Reihenfolge.
quelle
brauche Bestellung
oder brauche keine Bestellung
quelle
Hier habe ich doppelte Namenswerte aus mainArray entfernt und das Ergebnis in NSMutableArray (listOfUsers) gespeichert.
quelle
Beachten Sie, dass Sie bei einem sortierten Array nicht mit jedem anderen Element im Array vergleichen müssen, sondern nur mit dem letzten Element. Dies sollte viel schneller sein als die Überprüfung aller Elemente.
Es sieht so aus, als ob die
NSOrderedSet
Antworten, die ebenfalls vorgeschlagen werden, viel weniger Code erfordern. Wenn Sie jedochNSOrderedSet
aus irgendeinem Grund keinen verwenden können und ein sortiertes Array haben, ist meine Lösung meiner Meinung nach die schnellste. Ich bin mir nicht sicher, wie es mit der Geschwindigkeit derNSOrderedSet
Lösungen verglichen wird. Beachten Sie auch, dass mein Code mit überprüftisEqualToString:
, sodass dieselbe Buchstabenfolge nicht mehr als einmal in angezeigt wirdnewArray
. Ich bin nicht sicher, ob dieNSOrderedSet
Lösungen Duplikate basierend auf dem Wert oder basierend auf dem Speicherort entfernen.In meinem Beispiel wird davon
sortedSourceArray
ausgegangen, dass nurNSString
s, nurNSMutableString
s oder eine Mischung aus beiden enthalten ist. WennsortedSourceArray
stattdessen nurNSNumber
s oder nurNSDate
s enthält, können Sie ersetzenmit
und es sollte perfekt funktionieren. Wenn es
sortedSourceArray
eine Mischung ausNSString
s,NSNumber
s und / oderNSDate
s enthält, wird es wahrscheinlich abstürzen.quelle
Es gibt einen KVC- Objektoperator , der eine elegantere Lösung bietet.
uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];
Hier ist eine NSArray-Kategorie .quelle
Eine weitere einfache Möglichkeit, die Sie ausprobieren können, um vor dem Hinzufügen eines Objekts zum Array keinen doppelten Wert hinzuzufügen: -
// Angenommen, mutableArray wird zugewiesen und initialisiert und enthält einen Wert
quelle
Entfernen Sie doppelte Werte aus NSMutableArray in Objective-C
quelle
Hier ist der Code zum Entfernen doppelter Werte aus dem NSMutable Array. .es wird für Sie arbeiten. myArray ist Ihr veränderbares Array, mit dem Sie doppelte Werte entfernen möchten.
quelle
Verwenden
Orderedset
wird den Trick machen. Dadurch werden die Duplikate aus dem Array entfernt und die Reihenfolge beibehalten, die normalerweise nicht festgelegt istquelle
Verwenden Sie einfach diesen einfachen Code:
da nsset keine doppelten Werte zulässt und alle Objekte ein Array zurückgeben
quelle
NSOrderedSet
insteed vonNSSet
.