Merge two NSArrays consisting of dictionaries, based on a parameter in dictionaries

Go To StackoverFlow.com

3

I have a NSMutableArray and a NSArray. Both consist of elements that are NSDictionarys themselves. A sample structure of both is as follows:

NSMutableArray
[
    {
        objectId = 4274;
        name = orange;
        price = 45;
        status = approved;
    },
        {
        objectId = 9035;
        name = apple;
        price = 56;
        status = approved;
    },
        {
        objectId = 7336;
        name = banana;
        price = 48;
        status = approved;
    }
    .
    .
    .
    .
]

and NSAraay is

NSArray
[
    {
        objectId = 4274;
        name = orange;
        price = 106;
        status = not_approved;
    },
        {
        objectId = 5503;
        name = apple;
        price = 56;
        status = approved;
    }
]

What I want is to merge these two arrays so that, if any element in NSArray has same objectId as any element in NSMutableArray, element in NSArray should overwrite on element in NSMutableArray.

So in this case final merged array should look like this

MergedArray
    [
        {
            objectId = 4274;
            name = orange;
            price = 106;
            status = not_approved;
        },
            {
            objectId = 9035;
            name = apple;
            price = 56;
            status = approved;
        },
            {
            objectId = 7336;
            name = banana;
            price = 48;
            status = approved;
        },
           {
            objectId = 5503;
            name = apple;
            price = 56;
            status = approved;
        }
        .
        .
        .
        .
    ]

Only way to this I know is to iterate through both arrays and merge. Is there any better way? Any help will be greatly appreciated.

EDIT:

Following dasblinkenlights suggestion, I did it following way

    -(NSMutableArray*)mergeTwoArray:(NSArray*)array1 :(NSArray*)array2
    {
//array1 will overwrite on array2
    NSSet* parentSet = [NSSet setWithArray:array2];

        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        for (NSDictionary *item in parentSet) 
           [dict setObject: item forKey: [item objectForKey:@"objectId"]];


        NSLog(@"initial dictionary is %@",dict);
        for (NSDictionary *item in array1)            
            [dict setObject: item forKey: [item objectForKey:@"objectId"]];

        NSLog(@"final dictionary is %@ with all values %@", dict,[dict allValues]);

        return [NSMutableArray arrayWithArray:[dict allValues]];
    }
2012-04-05 14:44
by chatur
>9035 appears twice in your merged array. Is that intentional? - Phillip Mills 2012-04-05 14:48
No..!! I will edit question. Thanks for pointing ou - chatur 2012-04-05 14:52


2

Since your objectId value can be used as a unique key, you could potentially create an NSMutableDictionary on the side, populate it with NSDictionary objects from the first array using objectId value as the key, go through the second array, do the overwrites, and finally harvest the values of the resultant NSMutableDictionary into your final output.

Note that this approach might be helpful only if your arrays are relatively long (1000+ items). If you deal with 10..100 items, I wouldn't bother, and code two nested loops as you suggested.

2012-04-05 14:52
by dasblinkenlight
Thanks a lot. I merged arrays the way you suggested - chatur 2012-04-06 07:10


1

I would recommend iterating through both arrays and merging, but first sort them. Once sorted, you can merge two arrays in O(N) time. For most purposes, this is about as fast as you can get, and it requires very little code.

If they are large enough that the sort is a bottleneck, you could get fancy using an NSSet: put the (elements of the) over-riding array in the set first, and then add the elements of the original array. But you would have to implement an isEqual method for your elements. In this case, it would mean that your elements would no longer be NSDictionary, but rather a class that inherits from NSDictionary but implements the isEqual method to compare the object ID fields.

Because NSSet gives amortized constant time access, this would be faster, if the arrays are large, since there is no sort phase.

2012-04-05 14:54
by DRVic
Ads