Frage

NSArray hat nützliche Methoden Objekte für bestimmte Indizes finden

// To find objects by indexes
- (id)objectAtIndex:(NSUInteger)index
- (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes

// To find index by object
- (NSUInteger)indexOfObject:(id)anObject

Allerdings möchte ich NSIndexSet (mehrere Indizes) für bestimmte Objekte erhalten. So etwas wie:

- (NSIndexSet *)indexesOfObjects:(NSArray *)objects

Diese Methode existiert nicht für NSArray. Bin ich etwas fehlt? Kennt jemand eine andere Standardmethode? Ansonsten muss ich dies als Kategorie-Methode schreiben.

War es hilfreich?

Lösung

Es könnte nützlich sein, es zu implementieren eine Reihe mit den Objekten angeben, zu finden, wie zum Beispiel:

- (NSIndexSet *) indicesOfObjectsInSet: (NSSet *) set
{
    if ( [set count] == 0 )
        return ( [NSIndexSet indexSet] );

    NSMutableIndexSet * indices = [NSMutableIndexSet indexSet];

    NSUInteger index = 0;
    for ( id obj in self )
    {
        if ( [set containsObject: obj] )
            [indices addIndex: index];

        index++;
    }

    return ( [[indices copy] autorelease] );
}

Dies erfordert jedes Objekt im Array besuchen, aber zumindest tut nur so einmal und Verwendung von schnellen Aufzählung macht während dies zu tun. eine NSSet verwenden und Testen jedes Objekt in dem Array gegenüber diesem Satz ist auch viel schneller als in einer Anordnung für die Aufnahme zu testen.

Es gibt eine mögliche Optimierung hier, aber es wäre in dem Fall zu brechen, wo ein einzelnes Objekt in den Empfangsarray mehrere Male gespeichert ist:

if ( [set containsObject: obj] )
{
    [indices addIndex: index];
    if ( [indices count] == [set count] )
        break;
}

Auf diese Weise, wenn Sie das Scannen eines 20'000-Element-Array für zwei Objekte und sie sind beide innerhalb der ersten zehn, werden Sie das Scannen der anderen 19'990 Objekte im Array vermeiden können. Wie ich sagte aber, das nicht hilft, wenn die Array Duplikate enthält, weil es so bald aufhören werde, wie es 2 Indizes gefunden wird (auch wenn sie beide auf das gleiche Objekt).

Having said that , ich mit Mike Kommentar über zustimmen. Wahrscheinlich werden Sie sich für die Einstellung einige Schmerzen kommen optimierungs Zeit. Es kann sich lohnen, über verschiedene Datentypen zu denken; zum Beispiel, während NSArray die logischste Wahl für einen einfachen flachen Behälter scheint, wenn Sie tatsächlich nicht die Bestelldaten müssen dann ist es besser, einen NSSet stattdessen zu verwenden; Dies hat den zusätzlichen Vorteil, dass es nicht das gleiche Objekt gespeichert werden (mit -isEqual: berechnet) zweimal. Wenn Sie nicht möchten Spur von Duplikaten zu halten, aber nicht Bestellung benötigen, können Sie NSCountedSet, die als NSSet verhält, außer es Spur hält, wie oft jede Objekte, ohne tatsächlich zu speichern Duplikate hinzugefügt / entfernt wurde.

Andere Tipps

Neuere Versionen NSArray (OSX 10.6 und iOS 4) stellt die indexesOfObjectsPassingTest: Methode.

NSIndexSet *indexesOfObjects = [[array1 indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [array2 containsObject:obj];
}];

Sie haben eine eigene Kategorie zu implementieren, soweit ich sehen kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top