Search code examples
iosobjective-cnsarrayios9.3

Better way to compare custom objects of two NSArray and list out distinct objects in those array's


I have a model object called car which has following attributes

  • Name
  • Color
  • Type

In an array(Name: oldArray) I have several car objects. In a common Interval I will hit an API and get an another array (Name: newArray) of several car object. I need to compare two arrays and get the list of unique Items and show it to user.

Conditions. 1. If the object from newArray is not in oldArray then I need to Inform user that he has a new car along with the car name 2. If the object from oldArray is not in newArray then I need to Inform User that he has sold his car along with the car name

I have created the following method

- (NSMutableArray *)getModifiedUserCarsFrom:(NSMutableArray *)savedCars NewCars:(NSMutableArray *)newCars {

    NSMutableArray *loopArray1;
    NSMutableArray *loopArray2;
    NSMutableArray *modifiedCars = [NSMutableArray array];

    if (newCars.count >= savedCars.count) {
        loopArray1 = newCars;
        loopArray2 = savedCars;
    } else {
        loopArray1 = savedCars;
        loopArray2 = newCars;
    }

    for (Car *old in loopArray1) {
        BOOL isCarExist = NO;
        for (Car *new in loopArray2) {
            if ([new.name isEqualToString:old.name]) {
                isCarExist = YES;
                break;
            }
        }
        if (!isCarExist) {
            [modifiedCars addObject:olde];
        }
    }
    return modifiedCars;
}

Is there any better and Faster method than this? Any comments and suggestions are Appreciated.


Solution

  • //Create NSSet from Array
    
    NSSet* oldset = [NSSet setWithArray:oldArray];
    NSSet* newset = [NSSet setWithArray:newArray];
    
    // retrieve the Name of the objects in newset
    NSSet* newset_names = [newset valueForKey:@"Name"]; 
    // only keep the objects of oldset whose 'Name' are not in newset_names
    NSSet* oldset_minus_newset = [oldset filteredSetUsingPredicate:
        [NSPredicate predicateWithFormat:@"NOT Name IN %@",newset_names]];
    
    //And Same can be used for find newset not have name in oldset 
    
    // retrieve the Name of the objects in oldset
    NSSet* oldset_names = [oldset valueForKey:@"Name"]; 
    // only keep the objects of newset whose 'Name' are not in oldset_names
    NSSet* new_minus_oldset = [newset filteredSetUsingPredicate:
        [NSPredicate predicateWithFormat:@"NOT Name IN %@",oldset_names]];
    
    //Now convert back to Array from sets
    NSArray *new_minus_oldArray = [new_minus_oldset allObjects];
    NSSet* oldset_minus_newArray = [oldset_minus_newset allObjects];