Flatten an NSArray
Asked Answered
D

4

22

I have an array like this:

array: (
    (
        "http://aaa/product/8_1371121323.png",
        "http://aaa/product/14_1371123271.png"
    ),
    (
        "http://aaa/product/9_1371121377.png"
    )
)

and I have to create another array from that one like this

array: (
    "http://aaa/product/8_1371121323.png",
    "http://aaa/product/14_1371123271.png",
    "http://aaa/product/9_1371121377.png"
)

How can I do that? Is it possible to combine all the objects and separate them using some string?

Distinction answered 13/6, 2013 at 12:42 Comment(0)
H
6

Sample Code :

NSMutableArray *mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < bigArray.count ; i++)
{
     [mainArray addObjectsFromArray:[bigArray objectAtIndex:i]];
}
NSLog(@"mainArray :: %@",mainArray);
Harmonica answered 13/6, 2013 at 12:50 Comment(7)
Maybe esear use NSMutableArray?) And in the end [[NSArray alloc] initWithArray:...]Goodkin
@Sk0prion: No need to use NSMutableArray till the OP wants add something later in the Array.Harmonica
@Vin: If array of arrays is too large, better to use NSMutableArray. If u use NSArray, in each iteration u create new array. It's not good affect to performance. In the end u can translate mutable array to not mutable. [NSArray arrayWithArray:mutableArr]Goodkin
@Sk0prion: Right Point. I didn't think about it. Thanks for pointing out.Is it ok now ?Harmonica
@Vin: Yes) But if need more performance, u can go throw array like this for(NSArray* smallArr in bigArray){ [mainArray addObjectsFromArray:smallArr]; } ; This code faster and cleanerGoodkin
@Sk0prion: Can you explain me why it's faster and cleaner ?Harmonica
@Vin: I don't know realy implementation of arrays, but I think it uses list structure for implementation of array. Imagine list with 10000 elements. If you need to access 1000 element of array, you need go throw 999 nodes of the list to access to 1000 element. But I not sure, maby it uses tree structure. Anyway you need some time to access some element of array. In my variant it goes successively throw structure, so it's faster. Cleaner- this code easier to read, anderstandGoodkin
S
114

It can be done in a single line if you like key-value coding (KVC). The @unionOfArrays collection operator does exactly what you are looking for.

You may have encountered KVC before in predicates, bindings and similar places, but it can also be called in normal Objective-C code like this:

NSArray *flatArray = [array valueForKeyPath: @"@unionOfArrays.self"];

There are other collection operators in KVC, all prefixed with an @ sign, as discussed here.

Summersault answered 13/6, 2013 at 15:47 Comment(2)
Very nice! I'm just curious: did you check if that works with more deeply nested arrays?Iambus
@MartinR pretty sure you can't get collection operators to work recursively to arbitrary depths, but this one works on multi-dimensional arrays. I posted a self-answered question with the results of a small experiment: https://mcmap.net/q/586776/-how-can-i-most-easily-flatten-a-three-dimensional-array-in-cocoa/644348Summersault
H
6

Sample Code :

NSMutableArray *mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < bigArray.count ; i++)
{
     [mainArray addObjectsFromArray:[bigArray objectAtIndex:i]];
}
NSLog(@"mainArray :: %@",mainArray);
Harmonica answered 13/6, 2013 at 12:50 Comment(7)
Maybe esear use NSMutableArray?) And in the end [[NSArray alloc] initWithArray:...]Goodkin
@Sk0prion: No need to use NSMutableArray till the OP wants add something later in the Array.Harmonica
@Vin: If array of arrays is too large, better to use NSMutableArray. If u use NSArray, in each iteration u create new array. It's not good affect to performance. In the end u can translate mutable array to not mutable. [NSArray arrayWithArray:mutableArr]Goodkin
@Sk0prion: Right Point. I didn't think about it. Thanks for pointing out.Is it ok now ?Harmonica
@Vin: Yes) But if need more performance, u can go throw array like this for(NSArray* smallArr in bigArray){ [mainArray addObjectsFromArray:smallArr]; } ; This code faster and cleanerGoodkin
@Sk0prion: Can you explain me why it's faster and cleaner ?Harmonica
@Vin: I don't know realy implementation of arrays, but I think it uses list structure for implementation of array. Imagine list with 10000 elements. If you need to access 1000 element of array, you need go throw 999 nodes of the list to access to 1000 element. But I not sure, maby it uses tree structure. Anyway you need some time to access some element of array. In my variant it goes successively throw structure, so it's faster. Cleaner- this code easier to read, anderstandGoodkin
A
1

Sample code:

NSArray* arrays = @(@(@"http://aaa/product/8_1371121323.png",@"http://aaa/product/14_1371123271.png"),@(@"http://aaa/product/9_1371121377.png"));
NSMutableArray* flatArray = [NSMutableArray array];
for (NSArray* innerArray in arrays) {
    [flatArray addObjectsFromArray:innerArray];
}

NSLog(@"%@",[flatArray componentsJoinedByString:@","]);
Alysonalysoun answered 13/6, 2013 at 12:58 Comment(2)
1) NSArray* arr = @[@[.., ..], @[..]]. 2) In the end you get array with 2 elements instead of 3.Goodkin
just pass an array.. i ignored first lineDistinction
F
-1
NSMutableArray *arr1 = [NSMutableArray arrayWithArray:[initialArray objectAtIndex:0]];
[arr1 addObjectsFromArray:[initialArray objectAtIndex:1]];

Now arr1 contains all the objects

Fabien answered 13/6, 2013 at 12:49 Comment(1)
This assumes that the input array only ever has exactly two sub-arrays.Giffy

© 2022 - 2024 — McMap. All rights reserved.