2

I just want to know if an object is in an array or not.

So I can use:

- (BOOL)containsObject:(id)anObj

But it would send -isEqual to every object in the array. Bad when there are thousands of them.

And then there is:

- (NSUInteger)indexOfObjectIdenticalTo:(id)anObject

which seems to only compare the memory addresses. I think this is faster. But a bit nasty to use, of course. One would have to check for NSNotFound.

Is -indexOfObjectIdenticalTo really the best option?

Proud Member
  • 40,078
  • 47
  • 146
  • 231

4 Answers4

2

But a bit nasty to use

Why? It seems to me that

if ([array indexOfObjectIdenticalTo: foo] != NSNotFound)
{
    // do what you need
}

is not much more nasty than

if ([array containsObject: foo])
{
    // do what you need
}

Which one you choose depends on what equality semantics you use. You almost certainly want to use -containsObject: for arrays containing NSStrings or NSNumbers because -isEqual: gives the correct equality semantics.

Both methods, by the way are O(n) which is where the real performance problem is. If the idea of a linear search is a problem, consider a different data structure e.g. based on NSDictionary.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Like you can see yourself the second one is a lot shorter and has less instructions. So yes, comparing to NSNotFound is somewhat nasty :=) – Proud Member Apr 28 '11 at 11:40
  • +1 for the O(n) thing. Yes this would suck. Making use of the powerful hash function of dictionaries is a good idea. Thanks. – Proud Member Apr 28 '11 at 11:42
2

if you really need this often, you can create an instance method by category:

@interface NSArray (MONStuff)
- (BOOL)mon_containsObject:(id)object;
@end


@implementation NSArray (MONStuff)

- (BOOL)mon_containsObject:(id)object {
  return NSNotFound != [self indexOfObjectIdenticalTo:arg];
}

@end

or these's also CFArrayContainsValue.

a simple function would also suffice.

justin
  • 104,054
  • 14
  • 179
  • 226
  • A good simplification of the interface. However, i would name it mon_containsObjectIdenticalTo: to mirror the indexOfObject: indexOfObjectIdenticalTo: pair. – JeremyP Apr 28 '11 at 12:48
1

As per your explaining and comparison indexOfObjectIdenticalTo seems me the first choice to use..

Here is one more SO post ..

indexOfObject vs. indexOfObjectIdenticalTo

Community
  • 1
  • 1
Jhaliya - Praveen Sharma
  • 31,697
  • 9
  • 72
  • 76
1

If possible (for example if sorting order is irrelevant) you could use an NSDictionary instead, with your object as keys and values of [NSNull null]. Note that the objects get copied when used as keys ! Your objects would need to implement the - (NSUInteger)hash method.

Also see the excellent NSArray or NSSet, NSDictionary or NSMapTable analysis from Matt Gallagher.

DarkDust
  • 90,870
  • 19
  • 190
  • 224