Is there a way to tell if a certain object is in an NSArray? The way I am adding objects to my array makes it possible for the same object to be added multiple times and I wanted to see if there was a way to see if it was already there (anywhere) in that array.
The NSArray containsObject: method is precisely for this purpose, its full signature being:
- (BOOL)containsObject:(id)anObject
See the full NSArray Class Reference docs for more information.
if([yourArray indexOfObject:yourObject] == NSNotFound) {
// your object is not in here
}
Edit: middaparkas approach is way better (if you don't want the index …)!
Related
I have an 3 NSMutableArray objects that contain CMTime objects. How can I iterate through all three of them in an efficient manner and find out if there are duplicate values in all three? For example, I'm iterating through one of time and reading the value and storing it in x. Now, I want to see if x occurs (at any position) within the other two arrays. I tried looking for a contains method, but couldn't find one. I did come across filterUsingPredicate, but I'm not sure if this is the best way of doing it nor how to actually use predicates.
I tried looking for a contains method, but couldn't find one.
Use indexOfObject:
like this:
if ([array indexOfObject:object] != NSNotFound) {
// object found
}
else {
// object not found
}
You can use ([yourArray indexOfObject:x] != NSNotFound) in place of your missing contains method. However, if you're doing this quickly, often, or with a lot of elements, you should consider using NSMutableOrderedSet, which is ordered like NSMutableArray, but offers a quick and efficient contains method, as well as allowing quick operations like union and intersection, which might allow you to redesign your algorithm to iterate through your elements much less.
I want to add items to mutable array from a dictionary. Problem is I want to check existing array items before adding new item. If same item is already there in the array, I want to replace it. else add the new item.
How could I do it?
You could perhaps use an NSMutableSet rather than an NSMutableArray. The addObject method on NSMutableSet will only "add a given object to the set, if it is not already a member."
If you'd like to check membership before adding to the set anyway, you can check the result of:
[mySet containsObject:myObjectFromDictionary]
...which returns a simple BOOL value indicating whether the set already contains an object whose isEqual method returns true when your object is passed to it.
(For a little extra functionality, NSCountedSet will keep track of the number of objects added to the "set" for which isEqual: returns true)
You could compare the result of : [yourArray indexOfObject:yourObject]; against NSNotFound to know if the object is in the array.
It will give you the index of the object to replace, or if it is equal to NSNotFound, you will add it.
Objects equality is tested with isEqual: method.
NSArray class reference.
On the face of it, both Vincent's and Rich's answers are correct.
However, there is a conceptual issue in the original question that hasn't been addressed.
Namely, that "membership in an array" via indexOfObject: (or containsObject: in a set) is ultimately done by comparing the two objects using isEqual:.
If isEqual: returns YES, then the two objects better had damned well be functionally identical in your code or else you have other, significantly more serious, problems in your design and implementation.
Thus, the real question should be "How do I detect if an object is already in an array and not add it?" and Rich's and Vincent's answer are both still correct.
I.e. you should only need to check for presence and, if present, take no action.
(Note that there are esoteric situations where replacement is actually warranted, but they are both truly esoteric and not generally used within the context of a mutable collection)
I understand that:
(NSArray *)methodName
would return an array.
(UIImageView *)methodName
would return an imageview.
But how about if I wanted to return an Array of ImageViews?
If you're worried about it not being very clear about the fact that the array has UIImageViews, you can specify it on the name of the method, something like:
-(NSArray *)imageViewsForSomething:(id)something;
Otherwise, there's no reason you'd need to return explicitly an array of UIImageViews, an NSArray will do the trick.
Arrays and other container objects cannot be type in Objective-C like you can di in java.
One possible solution would be to subclass the NSArray class
NSArray is a stack of memory which stores object you add to it.
To store imagesviews, create an object of imageview and insert it in the array.
If you have to create long list of imageviews, you can create them using some iterative loop and add them in the array.
The array will hold on the imagesviews in it.
I am a newbie here, sorry if maid a mistake in above answer...
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?
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.
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.
As per your explaining and comparison indexOfObjectIdenticalTo seems me the first choice to use..
Here is one more SO post ..
indexOfObject vs. indexOfObjectIdenticalTo
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.
I am making a book application. To move to the next topic I am using a button. The Button works as it moves to the next topic, but at the end of the file my application gets the message obj_fatal and it crashes. If I knew how many objects there are in my NSArray then the problem will be solved. I am getting the details from a .plist file and storing it in to a array.
So if any one knows how, please let me know.
Thanks in advance.
Viral.
-[NSArray count]
Alternatively, if you prefer the look and feel of a property, you can do the following, assuming your NSArray is called myArray:
myArray.count
which is the same as #shosti's method, but looks different.
The difference is readability. So you could have:
if ([myArray count] > 0)
or you could have
if (myArray.count > 0)
which probably looks neater.
Both answers are good and correct. Whichever you choose depends on your coding style. As I said, both ways accomplish the same thing and call the same getter method.
Hope that helps.