2013-06-14 20 views
13

Ben bu gibi bir dizi olduğunu varsayalım:Kakao'da üç boyutlu bir diziyi en kolay nasıl düzleştirebilirim?

NSArray *threeDimensionalArray = @[ 
@[  
    @[ @"Peter", @"Paul", @"Mary" ], @[ @"Joe", @"Jane" ] 
    ], 
@[ 
    @[ @"Alice", @"Bob" ] 
    ] 
]; 

ve bunu olmak istiyorum:

@[ @"Peter", @"Paul", @"Mary", @"Joe", @"Jane", @"Alice", @"Bob" ] 

nasıl en kolay bu düzleştirilmiş diziyi oluşturabilir?

+0

+1. –

cevap

26

Anahtar-değer kodlaması (KVC) toplama operatörü @unionOfArrays bir dizi diziyi düzleştirir, böylece iki kez uygulayarak istenen sonucu verir.

Toplama operatörleri (@count dışında) bir koleksiyon özelliğine giden anahtar yollara ihtiyaç duyar ve nesnelerimiz zaten diziler (ve dolayısıyla koleksiyonlar) kendileri olduğundan, anahtar yolun self olması gerekir.

Bu nedenle 3D dizi düzleştirmek için aşağıdaki KVC çağrıyı veren, self anahtar yolu ile iki kez @unionOfArrays uygulamak gerekir:

NSArray *flattenedArray = [threeDimensionalArray valueForKeyPath: @"@[email protected]"]; 
1

Ben Konuyu biraz eski olduğunu biliyoruz, ama bir çözüm gerekli Derinliklerin sayısının çok önemli olmadığı yerler. NSArray'daki bir kategoriye aşağıdaki yöntemler eklenebilir. Düzgün çalışan İşte

// This is the method that would be used from an outside class 
- (NSArray *)flatten { 
    NSArray *array = self; 
    while (![array isFlattened]) { 
     array = [array flattenOneLevel]; 
    } 
    return [NSArray arrayWithArray:array]; 
} 

- (NSArray *)flattenOneLevel { 
    NSMutableArray *array = [NSMutableArray array]; 
    for (id object in self) { 
     [object isKindOfClass:self.class] ? [array addObjectsFromArray:object] : [array addObject:object]; 
    } 
    return array; 
} 

- (BOOL)isFlattened { 
    BOOL flattened = YES; 
    for (id object in self) { 
     if ([object isKindOfClass:self.class]) { 
      flattened = NO; 
      break; 
     } 
    } 
    return flattened; 
} 

bunu sağlamak için bu yöntemlerin test var: Ben de bu yöntemler için testi dahil ettik

it(@"should flatten an array", ^{ 
    NSArray *initialArray = @[@[@23, @354, @1, @[@7], @[@[@3]]], @[@[@890], @2, @[@[@6], @8]]]; 
    NSArray *expectedArray = @[@23, @354, @1, @7, @3, @890, @2, @6, @8]; 
    expect([initialArray flatten]).equal(expectedArray); 
}); 
0

(daha fazla bellek alacak özyineleme kullanarak alternatif bir cevap,

- (NSArray *) flatten; 
{ 
    NSMutableArray *flattedArray = [NSMutableArray new]; 

    for (id item in self) { 
     if ([[item class] isSubclassOfClass:[NSArray class]]) { 
      [flattedArray addObjectsFromArray:[item flatten]]; 
     } else { 
      [flattedArray addObject:item]; 
     } 
    } 

    return flattedArray; 
} 

Ve uzanan testler: yığın), ancak özyineleme isteyenler için, daha basittir okumak için

Soru ve cevap için şık bir çözüm için
+ (void) unitTests; 
{ 
    NSArray *flattenedArray; 

    NSArray *initialArray1 = @[@[@23, @354, @1, @[@7], @[@[@3]]], @[@[@890], @2, @[@[@6], @8]]]; 
    NSArray *expectedArray1 = @[@23, @354, @1, @7, @3, @890, @2, @6, @8]; 
    flattenedArray = [initialArray1 flatten]; 
    SPASLogDetail(@"flattenedArray: %@", flattenedArray); 
    AssertIf(![flattenedArray isEqualToArray:expectedArray1], @"Arrays are not equal"); 

    NSArray *initialArray2 = @[@[@23, @354, @1, [@[@7] mutableCopy], @[@[@3]]], @[[@[@890] mutableCopy], @2, @[@[@6], @8]]]; 
    NSArray *expectedArray2 = expectedArray1; 
    flattenedArray = [initialArray2 flatten]; 
    SPASLogDetail(@"flattenedArray: %@", flattenedArray); 
    AssertIf(![flattenedArray isEqualToArray:expectedArray2], @"Arrays are not equal"); 
} 
İlgili konular