Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put objects in an NSArray into an NSSet?

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.

like image 240
conorgriffin Avatar asked Mar 06 '10 02:03

conorgriffin


People also ask

How do you declare NSArray in Objective C?

In Objective-C, the compiler generates code that makes an underlying call to the init(objects:count:) method. id objects[] = { someObject, @"Hello, World!", @42 }; NSUInteger count = sizeof(objects) / sizeof(id); NSArray *array = [NSArray arrayWithObjects:objects count:count];

Can NSArray contain nil?

arrays can't contain nil.

What is Array and NSArray in Swift?

Array is a struct, therefore it is a value type in Swift. NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray .

What is an Nsset?

An object representing a static, unordered collection of unique objects.


2 Answers

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.

like image 192
indragie Avatar answered Oct 03 '22 20:10

indragie


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] 
like image 20
Anurag Avatar answered Oct 03 '22 21:10

Anurag