Come trasformare un NSArray di una stringa in un array di stringhe univoche, nello stesso ordine?

Se si dispone di un NSArray di stringhe

{ @"ONE", @"ONE", @"ONE", "TWO", @"THREE", @"THREE" }

Come faccio a girare che in

{ @"ONE", @"TWO", @"THREE" }

..dove la matrice che segue lo stesso ordine come l’originale. Penso che si può trasformare un array in un NSSet per ottenere oggetti unici, ma se lo si accende di nuovo in un array non sono garantiti per ottenere lo stesso ordine..

InformationsquelleAutor cannyboy | 2010-11-17

 

5 Replies
  1. 49

    Il mio pensiero iniziale era che si potesse fare:

    NSArray * a = [NSArray arrayWithObjects:@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE", nil];
    NSLog(@"%@", [a valueForKeyPath:@"@distinctUnionOfObjects.self"]);

    Ma che non mantenere l’ordine. Pertanto, è necessario farlo manualmente:

    NSArray * a = [NSArray arrayWithObjects:@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE", nil];
    NSMutableArray * unique = [NSMutableArray array];
    NSMutableSet * processed = [NSMutableSet set];
    for (NSString * string in a) {
      if ([processed containsObject:string] == NO) {
        [unique addObject:string];
        [processed addObject:string];
      }
    }

    Io uso un NSMutableSet per determinare se l’ho già imbattuto in questa voce prima (invece di [unique containsObject:string], dato un set di un O(1) tempo di ricerca, e un array è O(n) tempo di ricerca. Se si tratta solo di un piccolo numero di oggetti, quindi questo non importa. Tuttavia, se la matrice di origine è molto grande, quindi utilizzando il set per determinare l’unicità può aggiungere un po ‘ di una spinta in velocità. (tuttavia, è necessario utilizzare gli Strumenti per analizzare il tuo codice e vedere se è necessario)

    • Davvero non è la più intuitiva, cosa che @distinctUnionOfObjects scombina l’ordine (implementazioni, sembra che il vecchio setWithArray: / allObjects), come si prende e restituisce un array.
    • Grazie per questo post. Ho trovato molto utile, tuttavia, ho anche scoperto che se si sta solo cercando di caricare una seconda serie dal primo array con duplicati non ammessi, quindi non hai bisogno NSMutableSet. si può semplicemente utilizzare il ciclo for e l’istruzione if per controllare ogni oggetto e aggiungere, se necessario. Molto utile. Grazie
  2. 48

    Si potrebbe fare così:

    NSArray * uniqueArray = [[NSOrderedSet orderedSetWithArray:duplicatesArray] array];

    In questo modo, è anche mantenere l’ordine!

    • che è di destra, ma dovrebbe essere NSArray * uniqueArray = [[NSOrderedSet orderedSetWithArray:duplicatesArray] allObjects]
  3. 6

    Penso che Si può Fare questo Con che

    NSArray * uniqueArray = [[Yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

    spero che questo vi aiuterà

    • +1: Questo è quello che stavo cercando. Tuttavia, questo non soddisfa i requisiti del richiedente come questo non mantenere l’ordine della matrice originale… (1)[Yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"] non rispetta l’ordine e (2) sortedArrayUsingSelector:@selector(caseInsensitiveCompare:) ovviamente ordina l’array… Se stai cercando un modo per filtrare i duplicati e ordinare alfabeticamente la matrice finale”, questo è quello per voi. 😀
  4. 0

    Hmm.. si potrebbe utilizzare un ciclo ?

    NSMutableArray *newarray = [[NSMutableArray alloc] init];
    NSString *laststring = nil;
    for (NSString *currentstring in oldarray) 
    {
       if (![currentstring isEqualtoString:laststring]) [newarray addObject:currentstring];
       laststring = currentstring
    }
    • +1 intelligente utilizzando l’ultima stringa per il confronto
    • grazie .. dipende se l’array originale è davvero ordinato in quel modo… se qualcosa di simile ( “uno”, “uno”, “due”, “uno”, “tre” ) è possibile in quanto l’array originale non funziona.
    • Um, ma che funziona solo se identici elementi sono sempre adiacenti nell’array, giusto? In questo caso, questo sembra essere vero, ma chi lo sa…
    • Si mi ha battuto… 🙂
  5. 0

    Ecco una bella categoria che definisce un operatore su misura come @distinctUnionOfObjects, tranne che funziona solo su stringhe e mantenere la loro originale ordine. Nota: non ordinare le stringhe per voi. Lascia intatto solo il primo esempio di ciò sono le stringhe ripetute.

    Uso:

    #import "NSArray+orderedDistinctUnionOfStrings.h"
    ...
    //if you feed it an array that has already been ordered, it will work as expected
    NSArray *myArray = @[@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE"];
    NSArray *myUniqueArray = [myArray valueForKeyPath:@"@orderedDistinctUnionOfStrings.self"];

    Di uscita:

    myUniqueArray = ( "ONE", "TWO", "THREE" )

    .h:

    #import <Foundation/Foundation.h>
    
    @interface NSArray (orderedDistinctUnionOfStrings)
    
    @end

    .m file:

    #import "NSArray+orderedDistinctUnionOfObjects.h"
    
    @implementation NSArray (orderedDistinctUnionOfObjects)
    
    - (id) _orderedDistinctUnionOfStringsForKeyPath:(NSString*)keyPath {
        NSMutableIndexSet *removeIndexes = [NSMutableIndexSet indexSet];
    
        for (NSUInteger i = 0, n = self.count; i < n; ++i) {
            if ([removeIndexes containsIndex:i]) {
                continue;
            }
            NSString *str1 = [[self objectAtIndex:i] valueForKeyPath:keyPath];
    
            for (NSUInteger j = i+1; j < n; ++j) {
                if ([removeIndexes containsIndex:j]) {
                    continue;
                }
                id obj = [self objectAtIndex:j];
                NSString *str2 = [obj valueForKeyPath:keyPath];
                if ([str1 isEqualToString:str2]) {
                    [removeIndexes addIndex:j];
                }
            }
        }
    
        NSMutableArray *myMutableCopy = [self mutableCopy];
        [myMutableCopy removeObjectsAtIndexes:removeIndexes];
    
        return [[NSArray arrayWithArray:myMutableCopy] valueForKeyPath:[NSString stringWithFormat:@"@unionOfObjects.%@", keyPath]];
    }
    
    @end

    E qui è un’eccellente lettura su come generare i propri operatori, e demistifica (da un po’) come funziona: http://bou.io/KVCCustomOperators.html

Lascia un commento