views:

745

answers:

2

Hi all, I have some NSDictionary objects stored in an NSArray called telephoneArray. I fetch the values for the key number and then replace the NSDictionary I've just read with a new object at the same index in the array. I then want to put these new objects into an NSSet. How can this be achieved? See my unsuccessful attempt below.

    // Add all telephones to this branch
    for (int i=0; i<[telephoneArray count]; i++) {

        [newTelephone setBranch:newBranch];
        [newTelephone setNumber:[[telephoneArray objectAtIndex:i] valueForKey:@"number"]];

        NSLog(@"%@",[[telephoneArray objectAtIndex:i] valueForKey:@"number"]);
        [telephoneArray replaceObjectAtIndex:i withObject:newTelephone];
        NSLog(@"phone number %i = %@",i,[[telephoneArray objectAtIndex:i] valueForKey:@"number"]);

    }

    NSSet *telephoneSet = [NSSet setWithArray:telephoneArray];

    NSLog(@"telephoneArray=%i",[telephoneArray count]);
    NSLog(@"telephoneSet=%i",[[telephoneSet allObjects] count]);

OUTPUT:

2010-03-06 03:06:02.824 AIB[5160:6507] 063 81207
2010-03-06 03:06:02.824 AIB[5160:6507] phone number 0 = 063 81207
2010-03-06 03:06:02.825 AIB[5160:6507] 063 81624
2010-03-06 03:06:02.825 AIB[5160:6507] phone number 1 = 063 81624
2010-03-06 03:06:02.825 AIB[5160:6507] 063 81714
2010-03-06 03:06:02.826 AIB[5160:6507] phone number 2 = 063 81714
2010-03-06 03:06:02.826 AIB[5160:6507] 063 81715
2010-03-06 03:06:02.826 AIB[5160:6507] phone number 3 = 063 81715
2010-03-06 03:06:02.826 AIB[5160:6507] telephoneArray=4
2010-03-06 03:06:02.827 AIB[5160:6507] telephoneSet=1

With the code above, telephoneArray can have a count of between 1 and 5 but telephoneSet always has a value of 1. I assume there's an obvious mistake but I can't see where.

+4  A: 

This is not correct:

NSSet *telephoneSet = [[NSSet alloc] init];
[telephoneSet setByAddingObjectsFromArray:telephoneArray];

That method returns an NSSet which you are doing nothing with (it doesn't add the objects to telephoneSet, it creates a new NSSet). Do this instead:

NSSet *telephoneSet = [NSSet setWithArray:telephoneArray]

Also, note that a set cannot contain duplicates unlike an array. So if you have duplicate objects in your array and you put them in a set, the duplicates will be removed which can affect the object count.

macatomy
Thanks for spotting my error. Still not working though, I've amended my code above and included output from running it, I've added two extra NSLog statements to show they're not duplicates
Griffo
+1  A: 

Initially telephoneArray contains references to n distinct objects. After the loop ends, it does contain n references, but each one is pointing to the same newTelephone object.

Array can contain duplicates, so it doesn't matter. A Set cannot have duplicates, and your entire telephoneArray is composed of a single object basically, so you're seeing just one.

In your loop, you have to create a new object or get a telephone object from somewhere:

for (int i=0; i<[telephoneArray count]; i++) {
    // Create the new object first, or get it from somewhere.
    Telephone *newTelephone = [[Telephone alloc] init];
    [newTelephone setBranch:newBranch];
    [newTelephone setNumber:[[telephoneArray objectAtIndex:i] valueForKey:@"number"]];
    [telephoneArray replaceObjectAtIndex:i withObject:newTelephone];
    // the array holds a reference, so you could let go of newTelephone
    [newTelephone release];
}

Also, like PCWiz said, you don't need to allocate a new NSSet object in your case. Just call the class method setWithArray:.

NSSet *telephoneSet = [NSSet setWithArray:telephoneArray]
Anurag
Utter Genius!!! Thanks, it's 3:30am and this has been driving me crazy for hours! ;o)
Griffo
The case of the 3 am's. I've been there many times. It's the devil's time :)
Anurag