2013-06-14 6 views
13

は、私はこのような配列を持っていると言う3次元配列をCocoaで最も簡単に平坦化する方法はありますか?</p> <pre><code>NSArray *threeDimensionalArray = @[ @[ @[ @"Peter", @"Paul", @"Mary" ], @[ @"Joe", @"Jane" ] ], @[ @[ @"Alice", @"Bob" ] ] ]; </code></pre> <p>と私はそれがなりたい::

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

どのように私は最も簡単にこの平坦化された配列を作成することができますか?

+0

質問と回答の両方に+1、優雅な解決策。 –

答えて

26

キー値コーディング(KVC)コレクション演算子@unionOfArraysは、1レベルの配列を平坦化するため、2回適用することで目的の結果が得られます。

コレクション演算子(@count以外)には、コレクションプロパティへのキーパスが必要です。オブジェクトは既に配列(したがってコレクション)であるため、キーパスはselfでなければなりません。

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

私はこのスレッドが少し古いですが実現するが、私は解決策が必要:私たちは、そのための3D配列を平らにするために、次のKVCの呼び出しを得selfキーパスで二回@unionOfArraysを適用する必要が

深いレベルの数は本当に重要ではありません。次のメソッドをNSArrayのカテゴリに追加することができます。私も、これらのメソッドのテスト含まれている:

// 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; 
} 

ここにそれが正常に機能するように、これらのメソッドのテストです:

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

(上のより多くのメモリを取る再帰を使用して、代替の答えを、スタック)が、再帰を好きな人のために、読むために簡単です:

- (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; 
} 

とテストの拡張:

+ (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"); 
} 
関連する問題

 関連する問題