Selektiv zu entfernen und löschen von Objekten aus einem NSMutableArray in Swift
Grundlegende Frage. Was ist der beste Weg, um selektiv zu entfernen und löschen von Elementen aus einem mutable-Array in Swift?
Gibt es Optionen, die scheinen NICHT für diese geeignet, wie der Aufruf removeObject innerhalb einer
- für in-Schleife
- enumeration block
und andere, die Arbeit im Allgemeinen wie
- for-Schleife mit index + Aufruf removeObjectAtIndex, auch innerhalb der Schleife
- für in-Schleife für das Auffüllen einer arrayWithItemsToRemove und verwenden Sie dann originalArray.removeObjectsInArray(arrayWithItemsToRemove)
- mit .filter zum erstellen eines neuen array scheint wirklich nett zu sein, aber ich bin nicht ganz sicher, wie ich über das ersetzen der gesamte original-array
Gibt es eine empfohlene, einfache und sichere Methode zum entfernen von Elementen aus einem array? Einer von denen, die ich erwähnt oder etwas, was ich bin fehlt?
Wäre es schön wenn man verschiedene nimmt (mit vor-und Nachteilen) oder Einstellungen auf dieser. Ich immer noch kämpfen, Wahl des richtigen.
- Sprechen Sie über die Swift-Array? oder über NSMutableArray?
- Ein NSMutableArray. Danke für den Kommentar. Ich habe den Titel geändert, um klarzustellen, dass.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie wollen, um die Schleife und entfernen von Elementen aus einer
NSMutableArray
basiert auf einer Bedingung, können Sie mit einer Schleife das array in umgekehrter Reihenfolge (vom letzten index auf null), und entfernen Sie die Objekte, die die Bedingung erfüllen.Zum Beispiel, wenn Sie ein array von Integer-zahlen und wollen, entfernen Sie die zahlen durch drei teilbar, können Sie die Schleife wie diese:
Schleife in umgekehrter Reihenfolge ist sichergestellt, dass der index der array-Elemente immer noch zu prüfen, nicht ändern. Im vorwärts-Modus statt, wenn Sie entfernen zum Beispiel das erste element, dann das element zuvor bei index 1 änderung-index 0, und Sie haben zu berücksichtigen, dass in den code.
Nutzung von
removeObject
(was nicht funktioniert mit dem obigen code) wird nicht empfohlen, in einer Schleife aus performance-Gründen, da Ihre Implementierung durchläuft alle Elemente des Arrays und verwendetisEqualTo
um zu bestimmen, ob das Objekt entfernen oder nicht. Die Komplexität um, steigt von O(n) O(n^2) - in einem worst-case-Szenario, in dem alle Elemente des Arrays gelöscht werden, wird das array Durchlaufen wird einmal in der main-Schleife und Durchlaufen noch einmal für jedes element des Arrays. Also alle Lösung basierend auf der Aufzählung von Blöcken,for-in
usw., sollte vermieden werden, es sei denn, Sie haben einen guten Grund.filter
stattdessen ist eine gute alternative, und es ist, was ich verwenden würde, weil:Ist es vielleicht nicht ideal in allen Fällen, wenn, weil, als Sie sagte, es erzeugt ein neues array, anstatt auf den Betrieb im Ort.
array.removeAtIndex(index)
Beim arbeiten mit NSMutableArray Sie sollten nicht entfernen Sie Objekte, während Sie looping entlang der mutable-array selbst (es sei denn, looping rückwärts, wie bereits von Antonio ' s Antwort).
Eine gemeinsame Lösung ist, um eine unveränderliche Kopie des Arrays iterieren, auf die Kopie, und entfernen Sie Objekte selektiv auf die original-mutable-array durch den Aufruf "removeObject" oder durch aufrufen von "removeObjectAtIndex", aber Sie müssen berechnen den index, da die Indizes in den original-Arrays und das kopieren wird nicht passen, weil der Umzug (haben Sie zum verringern der "index entfernen" jedes mal, wenn ein Objekt entfernt wird).
Andere Lösung (besser) ist, um eine Schleife das array einmal erstellen einer NSIndexSet mit den Indizes der Objekte zu entfernen, und dann rufen "removeObjectsAtIndexes:" auf die mutable-array.
Siehe Dokumentation auf NSMutableArray ist "removeObjectsAtIndexes:" in Swift.
Einige der Optionen:
removeObjectAtIndex
: 1) Sie hat zu tun mit der Tatsache, dass, wenn Sie entfernen, wird der index der folgenden Objekt wird zum aktuellen index, so haben Sie sicher nicht, erhöht sich der index in diesem Fall; Sie können dies vermeiden, indem die Iteration rückwärts. 2) Jeder Aufruf vonremoveObjectAtIndex
ist O(n) (da muss es verschieben alle nachfolgenden Elemente nach vorne), so ist der Algorithmus O(n^2).removeObjectsInArray
: Der erste Teil ist O(n).removeObjectsInArray
verwendet eine hash-Tabelle, um zu testen, Elemente für die Entfernung effizient; hash-Tabelle Zugriff O(1) über dem Durchschnitt, aber O(n) worst-case, also ist der Algorithmus O(n) im Durchschnitt, aber O(n^2) worst-case.filter
zum erstellen eines neuen array: Das ist O(n). Es wird ein neues array erstellt.indexesOfObjectsPassingTest
), dann entfernen Sie Sie mitremoveObjectsAtIndexes
: ich glaube, das ist O(n). Es bedeutet nicht, erstellen Sie ein neues array.filterUsingPredicate
mit einem Prädikat, basierend auf einem block von deinem test: ich glaube, das ist auch O(n). Es bedeutet nicht, erstellen Sie ein neues array.NSMutableArray
.NSMutableArray
ist eine Klasse, die in der Foundation-framework, das sowohl in Objective-C und Swift.