1

Is there a way to use any of Apple's provided libraries or methods to zip two arrays together?

For example, if I have the following arrays

NSArray *one = @[@"foo", @"bar", @"bannana"];
NSArray *two = @[@"zebra", @"dog", @"cat"];

I want the result to be

@[@"foo", @"zebra", @"bar", @"dog", @"bannana", @"cat"]

I am aware that I could simply loop over them and add them to an other array, but I want to know if there is a better way to do it. I am not worried about performance.

You can assume the arrays are of the same length.

Edit :

I see now I was mistaken about the zip function, and that what I'm looking for here could probably be achieved in combination with flatten.

(I am constrained to using objective-c)

hhanesand
  • 990
  • 11
  • 28
  • Do they need to be ordered like that? Or can it simply be an append? – brandonscript Dec 06 '15 at 20:37
  • They need to be ordered. – hhanesand Dec 06 '15 at 20:38
  • What defines the order? There's no (built-in) programmatic way to order them like that because it's not alphabetical. Also, if you're talking about the Python [`zip`](http://stackoverflow.com/questions/4856717/javascript-equivalent-of-pythons-zip-function), this doesn't appear to be the same array manipulation. – brandonscript Dec 06 '15 at 20:39
  • @remus To my knowledge, a zip function combines the two arrays by picking one object from each array, alternating, until one of the arrays are empty. In this case I guess you could assume that the arrays have the same lengths. – hhanesand Dec 06 '15 at 20:40
  • Ah, well my bad. What would be the correct name for the operation I described in my previous comment? I am ordering them simply on the order of the two input arrays. Maybe I could do a zip + flatten? – hhanesand Dec 06 '15 at 20:43
  • 3
    There is nothing built in for this. Write your own code to merge the two arrays. – rmaddy Dec 06 '15 at 21:10

2 Answers2

2

There is nothing built-in, however I think this will do it (untested):

+ (NSArray *)flattenArray:(NSArray *)array1 withArray:(NSArray *)array2
{
    NSMutableArray *flattened = [NSMutableArray new];
    NSUInteger array1Count = [array1 count];
    NSUInteger array2Count = [array2 count];
    NSUInteger i;
    for (i = 0; i < array1Count && i < array2Count; i++) {
        [flattened addObject:array1[i]];
        [flattened addObject:array2[i]];
    }
    NSArray *overflow = nil;
    NSUInteger overflowCount = 0;
    if (array1Count >= i) {
        overflow = array1;
        overflowCount = array1Count;
    } else if (array2Count >= i) {
        overflow = array2;
        overflowCount = array2Count;
    }
    if (overflow) {
        for (; i < overflowCount; i++)
            [flattened addObject:overflow[i]];
    }
    return flattened;
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
2

It's absent from Objective-C. Definitely give the tick to trojanfoe. Apple has addressed the omission in Swift but you've been very explicit about that not being an option. So, pitching in on the race to write the neatest zip:

@implementation NSArray (Zip)

- (NSArray *)zip:(NSArray *)secondArray {
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:
                                                  self.count + secondArray.count];

    NSEnumerator *secondArrayEnumerator = [secondArray objectEnumerator];
    [self enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
        [result addObject:object];
        id pairObject = [secondArrayEnumerator nextObject];
        if (pairObject) [result addObject:pairObject];
    }];

    if ([secondArrayEnumerator nextObject]) {
        [result addObjectsFromArray:
            [secondArray subarrayWithRange:
                 NSMakeRange(self.length, 
                             secondArray.length-self.length)]];
    }

    return [result copy];
}

@end
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
Tommy
  • 99,986
  • 12
  • 185
  • 204