2013-03-29 7 views
6

Ho 2 nsarray, con gli stessi valori ma in ordine diverso.Confrontare due array con lo stesso valore ma con un ordine diverso

NSArray * array1 = {0,1,2,3}
NSArray * array2 = {2,3,1,0}

Ho bisogno di un metodo per determinare se due array abbiano gli stessi valori di un ordine diverso.

Tipo di

-(BOOL) isSameValues:(NSArray*)array1 and:(NSArray*)array2; 
+0

ordina em e quindi esegue un'iterazione per vedere se ogni elemento corrisponde. –

risposta

4
if ([[NSSet setWithArray:array1] isEqualToSet:[NSSet setWithArray:array2]]) { 
    // the objects are the same 
} 
+5

Questo considererebbe uguale a '[@ 1, @ 2, @ 2]' e '[@ 1, @ 1, @ 2]'. –

5

Update: questo non funzionerà se gli array hanno elementi duplicati!

È possibile creare due sNSSet con tali matrici e confrontarle.

NSArray * array1 = @[@0,@1,@2,@3]; 
NSArray * array2 = @[@2,@3,@1,@0]; 

NSSet *set1 = [NSSet setWithArray:array1]; 
NSSet *set2 = [NSSet setWithArray:array2]; 

NSLog(@"result %@", [set1 isEqualToSet:set2] ? @"YES" : @"NO"); 
+0

Questo considererebbe uguale a '[@ 1, @ 2, @ 2]' e '[@ 1, @ 1, @ 2]'. –

+0

Sì, hai ragione, l'esempio di OP mi ha buttato via –

+1

@ Martin: Non è chiaro che sia un comportamento scorretto. Contiene gli stessi valori. Se il numero di occorrenze è pertinente, basta invece renderlo un NSCountedSet. – Chuck

0

Prendere totale senza di elementi. Avere un contatore E metti il ​​doppio 'for loop' per analizzare ogni elemento l'uno dell'altro. Incrementa il contatore ad ogni abbinamento. Nota: questo è valido quando tutti gli elementi sono univoci.

Se diverso o non si conosce, ordinarli e abbinare uno a uno.

0

Un altro modo sarebbe utilizzare NSHashTable.

- (BOOL)array:(NSArray *)array1 containsTheSameObjectsAsArray:(NSArray *)array2 { 
    if (array1.count != array2.count) { 
     return NO; 
    } 
    NSHashTable *table = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory 
                capacity:array1.count]; 
    for (NSObject *object in array1) { 
     [table addObject:object]; 
    } 
    for (NSObject *object in array2) { 
     if (![table containsObject:object]) { 
      return NO; 
     } 
    } 
    return YES; 
} 

noti che NSHashTable richiede iOS 6+

18

È possibile utilizzare NSCountedSet a tal fine:

- (BOOL)isSameValues:(NSArray*)array1 and:(NSArray*)array2 
{ 
    NSCountedSet *set1 = [NSCountedSet setWithArray:array1]; 
    NSCountedSet *set2 = [NSCountedSet setWithArray:array2]; 
    return [set1 isEqualToSet:set2]; 
} 

NSCountedSet è una raccolta di diversi oggetti, dove ogni oggetto ha un contatore ad esso associato . Pertanto il risultato

NSArray *array1 = @[@0,@1,@2,@3]; 
NSArray *array2 = @[@2,@3,@1,@0]; 

è YES, ma per

NSArray *array1 = @[@1,@1,@3,@3]; 
NSArray *array2 = @[@3,@3,@3,@1]; 

il risultato è NO.

+0

Mi chiedo se l'ordinamento degli array e il confronto siano la stessa velocità o potenzialmente più veloci? –

+0

@DmitryShevchenko: I * presuppongo * che l'inserimento degli elementi dell'array nel set contato (utilizzando il metodo 'hash' per identificare elementi identici) sia più veloce rispetto all'ordinamento di tutti gli elementi (o almeno non più lento). Ma non posso dirti di sicuro. - In ogni caso, ciò funzionerebbe con array di elementi arbitrari, che potrebbero non essere comparabili. –

+2

questa è davvero la risposta giusta –