Question

I have an NSObject with NSStrings inside. How do I add objects with unique obj.name only to an NSMutableArray? I tried NSOrderedSet but it only works if you add NSString to an array and not objects with NSString inside.

Example.

@@interface MyObject : NSObject
@property (strong, nonatomic) NSString *name;
@end


NSMutableArray *array = {MyObject.name,MyObject.name,MyObject.name};

How do I make sure that no two MyObjects have the same name?

Was it helpful?

Solution

Use NSPredicate for seraching object in NSMutableArray if not present then add it to NSMutableArray. Try this.

  NSArray * filtered = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name = %@", @"MyObject.name"]];
  if(![array count])
        [array addObject:MyObject ]; 

OTHER TIPS

All NSSet classes use isEqual: in combination with hash: to compare equality. Because you have not redefined these simply storing two objects with the same name in a set will be possible as the NSObject implementation of isEqual: and hash: will be used.

The documentation of NSObject Protocol talks about overriding isEqual and hash. This previous answer on Stackoverflow details how to implement hash and isEqual correctly.

In your own implementation of hash you can use NSString's hash method.

Example

- (NSUInteger) hash {
    NSUInteger prime = 31;
    NSUInteger result = 1;

   result = prime * result + [super hash];
   result = prime * result + self.name == nil ? 0 : [self.name hash];

   return result;
}

- (bool) isEqual:(id)other {
   if (other == self) {
       return YES;
   }
   if (!other || ![other isKindOfClass:[self class]]) {
        return NO;
   }

   return [self.name isEqualToString:other.name];
}

Personally, I would use a NSMutableDictionary with MyObject.name as the key. That way all you would have to do is this:

if( myDictionary[MyObject.name] == nil )
{
    myDictionary[MyObject.name] = MyObject;
}

Much more efficient than using a regular NSMutableArray based on the number of additions you are doing. Plus if you want to get access to an array of all the values, all you have to do is:

NSArray *array = [myDictionary allValues];

The Big-O Runtime for NSPredicate is O(n) where the dictionary method is O(1).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top