Find index of an NSArray by passing value - iphone

Is it possible in an NSArray to find out if a given value exists or not in the array (without searching it using a for loop)? Any default random method. I went through the documentation, but didn't find much relevant.
Please also tell me about valueForKey method (I was unable to get that from doc).

The containsObject: method will usually give you what you're asking - while its name sounds like you are querying for a specific instance (i.e. two object with the same semantic value would not match) it actually invokes isEqual: on the objects so it is testing by value.
If you want the index of the item, as your title suggests, use indexOfObject:, it also invokes isEqual: to locate the match.
valueForKey: is for when you have an array of dictionaries; it looks up the key in each dictionary and returns and array of the results.

I believe you want to use the indexOfObject method. From the documentation:
indexOfObject:
Returns the lowest index whose
corresponding array value is equal to
a given object.
- (NSUInteger)indexOfObject:(id)anObject
Parameters
anObject
An object.
Return Value
The lowest index whose corresponding
array value is equal to anObject. If
none of the objects in the array is
equal to anObject, returns NSNotFound.
Discussion
Objects are considered equal if
isEqual: returns YES.
Important: If anObject is nil an
exception is raised.

You can use :
NSInteger idx = [myArray indexOfObject:obj];
to find index of object.
And to check if object is there or not in array you may use :
- (BOOL)containsObject:(id)anObject

Use NSPredicate to filter an NSArray based on NSDictionary
array = [dictionary filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(key == %#)", value]];
if([array count]>0)
{
value exists;
}

Combine objectAtIndex and indexOfObject like this:
[tmpArray objectAtIndex:[tmpArray indexOfObject:yourObject]];

Related

how do I get the index at which an Object has been added to an NSMutableArray?

I'm adding an object to a NSMutableArray like this:
[array addObject:myObject];
I now want to send a reference to my delegates of the Array Index where this object was added.
Is there an easy way to find out the index where my object was added in the array so that later I can call
[array objectAtIndex:index]
to get a reference back for it?
Thanks!
Rather than passing the index of an object (which could be incorrect) to your delegate, pass a reference to the object itself. If the delegate needs the index of the object in the array, it can figure it out itself using -indexOfObject: as Antonio MG describes. The index of any given object in a mutable array can change as objects are added, inserted, and deleted. Counting on indices to remain valid over any period of time is like leaving a jelly sandwich on the counter -- it's sure to attract bugs.
You need to serialize access to a mutable array and -addObject: always adds the object to the end of the array. Given those two assertions, you know the index of the next added object will always be the current length of the array. So the following will hold true:
NSUInteger nextIndex = [array count];
[array addObject:myObject];
// you can now tell your delegates that nextIndex is the index of myObject
Use this method for that:
index = [animalOptions indexOfObject:myObject];
The latest added object should be at [array count] - 1 index. You can always rely on "count - 1" scheme to determine the last index.
If you call addObject you always add the object at the end (so count - 1).
You can use "insertObject:atIndex:" to specify an index.
For your question: indexOfObject:
Direct after adding the object's index is array.count -1 .

Getting Index of an Object from NSArray?

i am trying to get index of an array through indexOfObject method as follows but when i try to log the value to test the index i get a garbage value.. for testing purposes i am having an array with values {57,56,58..} to get an index of lets say 56,
NSNumber *num = [NSNumber numberWithInteger:56];
NSInteger Aindex = [myArray indexOfObject:num];
NSLog(#" %d",Aindex);
the value i get is something like 2323421. what am i possibly doing wrong??
The index returned by indexOfObject will be the first index for an occurence of your object. Equality is tested using isEqual method.
The garbage value you get is probably equal to NSNotFound.
Try testing anIndex against it. The number you are looking for isn't probably in your array :
NSNumber *num=[NSNumber numberWithInteger:56];
NSInteger anIndex=[myArray indexOfObject:num];
if(NSNotFound == anIndex) {
NSLog(#"not found");
}
or log the content of the array to be sure :
NSLog(#"%#", myArray);
Folks,
When an object is not found in the array the indexOfObject method does NOT return a 'garbage' value. Many systems return an index of -1 if the item is not found.
However, on IOS - because the indexOfObject returns an UNSIGNED int (aka NSUInteger) the returned index must be greater than or equal to zero. Since 'zero' is a valid index there is no way to indicate to the caller that the object was not found -- except by returning an agreed upon constant value that we all can test upon. This constant agreed upon value is called NSNotFound.
The method:
- (NSUInteger)indexOfObject:(id)anObject;
will return NSNotFound if the object was not in the array. NSNotFound is a very large POSITIVE integer (usually 1 minus the maximum int on the platform).
NSNumber *num1 = [NSNumber numberWithInt:56];
NSNumber *num2 = [NSNumber numberWithInt:57];
NSNumber *num3 = [NSNumber numberWithInt:58];
NSMutableArray *myArray = [NSMutableArray arrayWithObjects:num1,num2,num3,nil];
NSNumber *num=[NSNumber numberWithInteger:58];
NSInteger Aindex=[myArray indexOfObject:num];
NSLog(#" %d",Aindex);
Its giving the correct output, may be u have done something wrong with storing objects in ur array.
Try this:
NSArray's indexOfObject: method. Such as the following:
NSUInteger fooIndex = [someArray indexOfObject: someObject];
If you're using Swift and optionals make sure they are unwrapped. You cannot search the index of objects that are optionals.
I just checked. Its working fine for me. Check if your array has the particular number. It will return such garbage values if element is not present.
indexOfObject methord will get the index of the corresponding string in that array if the string is like #"Test" and you find like #"TEST" Now this will retun an index like a long number

Getting length of an array inside a Dictionary Key

I'm sure this is a very obvious question but I'm not getting anywhere with it and I've been trying for half an hour or so now.
I have an NSMutableDictionary which has keys & values, obviously. Each key stores an array of objects. What I need to do is find a specific array in a key and get the list of the array. The catch is that I don't know the value of the key, I just know it's index. (EG: I know I need to find the array in the 2nd key).
I am almost certain this is a very easy & trivial thing to do but it's escaping me, I've only been doing Obj-C for a short while so not entirely at home with it yet!
Thanks,
Jack.
Use allKeys: to access the keys of your dictionary.
- (NSArray *)allKeys
Use as below .
NSArray* dictAllKeys = [dict allKeys];
if([dictAllKeys count] > 2)
{
NSArray* myArrayInDict = [dict objectForKey:[dictAllKeys objectAtIndex:1]];
// get the length of array in dict at 2nd key
int length = [myArrayInDict count];
}
The order will probably change if another key/value pair is added, it is a NSMutableDictionary. It is best not to rely on the order of a NSDictionary or NSSet.
Suggestion: Either use another container that does provide ordering such as NSMutableArray or find the item using the dictionary's value arrays, perhaps with NSPredicate.

why does '[self.pickerSubArray indexOfObject:self.txtSubCategory.text]' return '2147483647'?

why does '[self.pickerSubArray indexOfObject:self.txtSubCategory.text]' return '2147483647'; while the same string value argument '[self.pickerSubArray indexOfObject:#"Mark"]' brings up 4, as desired?
The Apple docs for NSArray (which I assume your object is, based on the name) say that indexOfObject: returns NSNotFound if the object does not match any in the array. NSNotFound is itself defined as NSIntegerMax which, as others have pointed out, is the value that you are getting back.
indexOfObject: uses isEqual: to compare the items, so in theory if the text is the same then it should be working. Perhaps the text is actually different in some way that you haven't noticed, such as case ("Mark" vs. "mark") or extra padding ("Mark" vs. "Mark ").
indexOfObject: returns NSNotFound if it can't find your exact object. NSNotFound is defined as NSIntegerMax, which is 2147483647.
Why is it doing that? I'm pretty sure indexOfObject: tests for an identical object, not an object with identical content.
e.g.
NSString *mark1 = [NSString stringWithString:#"Mark"];
NSString *mark2 = [NSString stringWithString:#"Mark"];
mark1 is not necissarily equal to mark2, because they're two different objects.
NSString *mark1 = [NSString stringWithObject:#"Mark"];
NSString *mark2 = mark1;
mark1 is equal to mark2;
BUT! Since the compiler is trying to minimize the memory footprint, it turns all literal strings in your code into one constant string. Which is why [[NSArray arrayWithObject:#"Mark"] indexOfObject:#"Mark"] works, but [[NSArray arrayWithObject:#"Mark"] indexOfObject:textField.text] doesn't work even if the text in textField.text is "Mark".
How do you fix it... well, indexOfObject: from the docs it looks like indexOfObject: is based on isEqual: so you should test if [self.txtSubCategory.text isEqual:#"Mark"]. to rule out the wrong value or a disconnected outlet, etc. After that, you may have to refactor to not use indexOfObject:
Just a guess about the number origin - it's a bad integer conversion. It was very probably meant to return -1.
That kindof leads me to believe that you might have found some badness in underlying libraries/languages.

Objective-C, How can I produce an array / list of strings and count for each?

My aim is to produce an array, which I can use to add section headers for a UITableView. I think the easiest way to do this, is to produce a sections array.
I want to create section headers for dates, where I'll have several or no rows for each.
So in my populate data array function, I want to populate a display array. So record 1, look for the first date in my display array, create a new array item if it doesn't exist, if it does exist add 1 to the count.
So I should end up with something like this.
arrDisplay(0).description = 1/June/2001; arrDisplay(0).value = 3;
arrDisplay(1).description = 2/June/2001; arrDisplay(1).value = 0;
arrDisplay(2).description = 3/June/2001; arrDisplay(2).value = 1;
arrDisplay(3).description = 5/June/2001; arrDisplay(3).value = 6;
My question is how do I create and use such an array with values, where I can add new elements of add to the count of existing elements and search for existing elements ?
I think, if i understand you, an NSMutableDictionary would work. (as NR4TR said) but, i think the object would be the description and the key would be the count. you could check for the key and get the count in the same gesture. if the return value of objectForKey is nil, it doesn't exist.
NSMutableDictionary *tableDictionary = [[NSMutableDictionary alloc] init];
NSString *displayKey = #"1/June/2001";
NSNumber *displayCount = [tableDictionary objectForKey:displayKey];
if (displayCount != nil) {
NSNumber *incrementedCount = [[NSNumber alloc] initWithInteger:[displayCount integerValue] + 1];
[tableDictionary removeObjectForKey:displayKey];
[tableDictionary setValue:incrementedCount
forKey:displayKey];
[incrementedCount release];
}
else {
NSNumber *initialCount = [[NSNumber alloc] initWithInteger:1];
[tableDictionary setValue:initialCount
forKey:displayKey];
[initialCount release];
}
EDIT: Hopefully this isn't pedantic, but I think a couple pointers will help.
Dictionaries, Sets, and Arrays all hold objects for retrieval. The manner of holding and retrieval desired drives the decision. I think of it based on the question 'what is the nature of the information that I have when I need an object being held?'
NSDictionary and NSMutableDictionary
Hold n objects per key. (I think...I haven't had to test a limit, but i know you can get an NSSet back as a value.)
KEY is more important than INDEX. I don't think of dictionaries as ordered. they know something and you need to ask the correct question.
NSArray and NSMutableArray
hold n objects in order.
INDEX is most important bit of information. (you can ask for the index of an object but, even here, the index is the important part)
you will typically drive table views with an array because the ordered nature of the array fits.
NSSet, NSMutableSet, and NSCountedSet
A collection of objects without order.
You can change any of these into the other with something like [nsset setFromArray:myArray];
and all of these things can hold the other as objects. I think an array as your top level is the correct thinking, but beyond that, it becomes an issue of implementation
Try array of dictionaries. Each dictionary contains two objects - section title and array of section rows.
If you want to have a description AND a rowcount then you can either create a class with those two properties and generate an NSArray of objects with that class or instead of all that you can just use an NSDictionary to store key/value lookups.
I think NSCountedSet is closest to what you want. It doesn't have an intrinsic order, but you can get an array out of it by providing a sort order.