0

I have a NSMutableArray that looks like the one below and want to look through and remove the objects that have the same realLocationName and ADD_LINE1 and leave just the realLocationName object.

my array now:

(
        {
        locationId = "12-11-2013 10:23:53";
        realLocationName = wauk;
    },
        {
        locationId = "01-02-2014 10:10:11";
        realLocationName = sdf;
    },
        {
        locationId = "01-02-2014 11:55:49";
        realLocationName = "514 COURT AVE";
    },
        {
        "ADD_CITY" = city;
        "ADD_LINE1" = "514 COURT AVE";
        "ADD_LINE2" = "";
        "ADD_STATE" = IA;
        "ADD_ZIP" = 50833;
        "BUSINESS_NAME" = "";
        "FIRST_NAME" = joe;
        "LAST_NAME" = smith;
    },
        {
        "ADD_CITY" = cty2;
        "ADD_LINE1" = "514 COURT AVE";
        "ADD_LINE2" = "";
        "ADD_STATE" = IA;
        "ADD_ZIP" = 50833;
        "BUSINESS_NAME" = "";
        "FIRST_NAME" = randy;
        "LAST_NAME" = red;
    }
)

What I am trying to get:

(
        {
        locationId = "12-11-2013 10:23:53";
        realLocationName = wauk;
    },
        {
        locationId = "01-02-2014 10:10:11";
        realLocationName = sdf;
    },
        {
        locationId = "01-02-2014 11:55:49";
        realLocationName = "514 COURT AVE";
    }
)

EDIT:

or this scenario: array =

(
            {
            locationId = "12-11-2013 10:23:53";
            realLocationName = wauk;
        },
            {
            locationId = "01-02-2014 10:10:11";
            realLocationName = sdf;
        },
            {
            "ADD_CITY" = city;
            "ADD_LINE1" = "514 COURT AVE";
            "ADD_LINE2" = "";
            "ADD_STATE" = IA;
            "ADD_ZIP" = 50833;
            "BUSINESS_NAME" = "";
            "FIRST_NAME" = joe;
            "LAST_NAME" = smith;
        },
            {
            "ADD_CITY" = cty2;
            "ADD_LINE1" = "514 COURT AVE";
            "ADD_LINE2" = "";
            "ADD_STATE" = IA;
            "ADD_ZIP" = 50833;
            "BUSINESS_NAME" = "";
            "FIRST_NAME" = randy;
            "LAST_NAME" = red;
        }
    )

and get this:

(
            {
            locationId = "12-11-2013 10:23:53";
            realLocationName = wauk;
        },
            {
            locationId = "01-02-2014 10:10:11";
            realLocationName = sdf;
        },
            {
            "ADD_CITY" = city;
            "ADD_LINE1" = "514 COURT AVE";
            "ADD_LINE2" = "";
            "ADD_STATE" = IA;
            "ADD_ZIP" = 50833;
            "BUSINESS_NAME" = "";
            "FIRST_NAME" = joe;
            "LAST_NAME" = smith;
        }
    )
Ekta Padaliya
  • 5,743
  • 3
  • 39
  • 51
BluGeni
  • 3,378
  • 8
  • 36
  • 64
  • Post what you have tried so far and explain what problem you are having with the code. – rmaddy Jan 02 '14 at 18:53
  • @rmaddy well thats the problem, I dont know how to remove duplicates from a dictionary/array and that is what I want to know how to do. – BluGeni Jan 02 '14 at 18:55

3 Answers3

1

You can use a set (NSMutableSet) to check whether a realLocationName added or not.

How this code works?

1) every object, I get the value of "realLocationName" key or "ADD_LINE1" key assuming that no object has both of these keys but one key exists definitely

2) the array is ordered that all "realLocationName" objects are in the beginning part - this is because it was a requirement that object with realLocationName are preferred that object with ADD_LINE1.

NSMutableArray *arr_noduplicates = [NSMutableArray array];
NSMutableSet *set_of_already_added = [NSMutableSet set];

for (NSDictionary *obj in originalArray) {
    NSString *str_value = [NSString stringWithFormat:@"%@%@", 
                          obj[@"realLocationName"] ? obj[@"realLocationName"] : @"", 
                          obj[@"ADD_LINE1"] ? obj[@"ADD_LINE1"] : @""];
    if (![set_of_already_added containsObject:str_value]) {
        [arr_noduplicates addObject:obj];
        [set_of_already_added addObject:str_value];
    }
}
nzs
  • 3,252
  • 17
  • 22
  • This is almost exactly what I need but there is a small problem, this method removes objects if they dont have realLocationNames. I would like to keep the objects if they dont have realLocationNames as long as they dont duplicate other reallocationnames or ADD_line1 – BluGeni Jan 02 '14 at 19:09
  • So the pseudo-code would be for the condition: add the current_object if current_object.reallocationnames is unique OR current_object. ADD_line1 is unique ? What if you have already a "abc" reallocationnames added and then you have a next object with ADD_line1=="abc"- you add it since it is a ADD_line1 type of object of reject it? – nzs Jan 02 '14 at 19:17
  • I want no duplicates. but want to keep the one with realLocationName over the ADD_LINE1 if there is are duplicates. – BluGeni Jan 02 '14 at 19:27
  • I added another example to my question to better explain it. – BluGeni Jan 02 '14 at 19:30
  • This is perfect, thank you for including the explanation with the answer to help me better understand how it works! – BluGeni Jan 02 '14 at 20:24
0

As removing object is not the cheapest operation on the NSMutableArray you could create another method that will return NSMutableArray object and as an attribute it will receive an original array.

-(NSMutableArray*)filterArray:(NSMutableArray*)originalArray

At the beginning new array will be empty. You will add new object at the end of the new array if any of the interesting you attributes is in object in array so far. You will repeat this algorithm while not reaching the end of the original array.

Julian
  • 9,299
  • 5
  • 48
  • 65
0

Try this, it may help you. I didn't test it..

mainArray is your data. And finalArray is the new mutable array where we are going to add filter objects.

for (NSDictionary *dict in mainArray) {
    if ([finalArray count] == 0) {
        [finalArray addObject:dict];
    }
    else {

        BOOL isStored = NO;

        for (NSDictionary *newDict in finalArray) {
            if ([newDict[@"realLocationName"] isEqualToString:dict[@"realLocationName"]] || [newDict[@"ADD_LINE1"] isEqualToString:dict[@"ADD_LINE1"]] ) {//Check first ADD_LINE1 value is there or not? then go with this condition
                isStored = YES;
                break;
            }
        }

        if (!isStored) {
            [finalArray addObject:dict];
        }
    }
}
Bhumeshwer katre
  • 4,671
  • 2
  • 19
  • 29