indexOfObject in an NSMutableArray returning garbage value - iphone

Trying to get index on an object in NSMutableArray. It is returning some garbage value, not getting why it is not returning index of particular item. Below is code i tried.
NSString *type = [dictRow valueForKey:#"type"];
if([arrSeatSel indexOfObject:type])
{
NSUInteger ind = [arrSeatSel indexOfObject:type];
[arrTotRows addObject:[arrSeatSel objectAtIndex:ind]];
}
type contains value "Gold". And arrSeatSel contains
(
"Gold:0",
"Silver:0",
"Bronze:1"
How to check that. Please guide.

The value you are getting is NSNotFound. You are getting NSNotFound because #"Gold" is not equal to #"Gold:0".
You should try the following
NSUInteger index = [arrSeatSel indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return [obj hasPrefix:type];
}];
if (index != NSNotFound) {
[arrTotRows addObject:[arrSeatSel objectAtIndex:index]];
}
UPDATE
-indexOfObjectPassingTest: is a running the following loop. NOTE: /* TEST */ is some code that returns true when the correct index is found.
NSUInteger index = NSNotFound;
for (NSUInteger i = 0; i < [array count]; ++i) {
if (/* TEST */) {
index = i;
break;
}
}
In my first sample, /* TEST */ is [obj hasPrefix:type]. The final for loop would look like.
NSUInteger index = NSNotFound;
for (NSUInteger i = 0; i < [arrSeatSel count]; ++i) {
if ([arrSeatSel[i] hasPrefix:type]) {
index = i;
break;
}
}
if (index != NSNotFound) {
[arrTotRows addObject:[arrSeatSel objectAtIndex:index]];
}
I like -indexOfObjectPassingTest: better.
The [obj hasPrefix:type] part is just a different way to comparing strings. Read the -hasPrefix: doc for more details.
Hope that answers all your questions.

Sometimes storing data properly can solve lot of hazzle. If I guess correctly
"Gold:0" denotes a circle of type Gold an its count 0.
You can try to reformat that to an array of items.
Such as
[
{
"Type": "Gold",
"Count": 0
},
{
"Type": "Silver",
"Count": 0
},
{
"Type": "Bronze",
"Count": 1
}
]
And then using predicate to find the index
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Type == %#",#"Gold"];
NSUInteger index = [types indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
[predicate evaluateWithObject:obj];
}];

You can try doing this.
[arrSeatSel enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
// object - will be your "type"
// idx - will be the index of your type.
}];
hope this helps.

If I'm reading that correctly, you're saying that arrSeatSel contains three NSStrings, #"Gold:0", #"Silver:0", and #"Bronze:1", correct?
And then your NSString* type is basically #"Gold"
The first thing is Gold and Gold:0 are different strings, and that's just for starter.
As you are searching for a string in the array, you should take each string out, and do a string matching, not just a comparison. What I'm saying is this:
NSString* str1 = #"This is a string";
NSString* str2 = #"This is a string";
if ( str1 == str 2 ) NSLog(#"Miracle does happen!")
The conditional would never be true even though both NSStrings contain the same value, they are different object, thus are different pointers pointing to different blocks of memory.
What you should do here is a string matching, I will recommend NSString's hasPrefix: method here, as it seems to fit your need.

Related

Returning the number of objectForKey

I have a part of my code that returns the numberOfRowsInSection.
Code
for (NSDictionary *consoleDictionary in [self arrayFromJSON]) {
if ([[consoleDictionary objectForKey:#"model"] isEqualToString:#"PlayStation 3"]) {
NSLog(#"%#", consoleDictionary);
}
}
Output
2013-02-03 22:37:08.468 PageControl01[5782:c07] {
console = PlayStation;
game = "007 Legends";
id = 1;
model = "PlayStation 3";
publisher = "Electronic Arts";
}
2013-02-03 22:37:08.478 PageControl01[5782:c07] {
console = PlayStation;
game = "Ace Combat: Assault Horizon";
id = 2;
model = "PlayStation 3";
publisher = Namco;
}
This one is apparently right because it logs all the "PlayStation 3" model. However, this is not what I need. I want to log the number of "PlayStation 3"'s. So I tweak the code a little bit and then this:
for (NSDictionary *consoleDictionary in [self arrayFromJSON]) {
if ([[consoleDictionary objectForKey:#"model"] isEqualToString:#"PlayStation 3"]) {
NSLog(#"%d", [consoleDictionary count]);
}
}
Output
2013-02-03 22:39:43.605 PageControl01[5816:c07] 5
2013-02-03 22:39:43.605 PageControl01[5816:c07] 5
This one is pretty near yet so close. Instead of logging the number 5, it should log the number 2 since there are only 2 "PlayStation 3".
Please help.
You don't need to explicitly loop through the array.
NSIndexSet *is = [array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[obj objectForKey:#"model"] isEqualToString:#"PlayStation 3"];
}];
int numOfPS3s = is.count;
It is logging the number 5 because there is 5 keys in each of your dictionaries (console, game, id, model, publisher). If instead of logging the [consoleDictionary count] you simply add one to an int counter each time, you would get the expected result in your counter at the end.
You can obtain the number of objects is a much more easier way: [self arrayFromJSON] is an array
Typically:
NSInteger nbPS3 = [[self arrayFromJSON] indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [obj[#"model"] isEqualToString:#"PlayStation 3"];
}].count
Yes, count is always the total count, not the index, not the count of matches. Using indexesOfObjectsPassingTest is the most direct solution for this specific question, but if you're interested in other techniques for iterating through your result set, but also keeping track of not only the object, but also the index, consider these two approaches, too:
for (NSInteger i = 0; i < [self.arrayFromJSON count]; i++) {
if ([[[self.arrayFromJSON objectAtIndex:i] objectForKey:#"model"] isEqualToString:#"PlayStation 3"]) {
NSLog(#"%d", i);
}
}
or
[self.arrayFromJSON enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([[obj objectForKey:#"model"] isEqualToString:#"PlayStation 3"]) {
NSLog(#"%d", idx);
}
}];
Obviously, if you're looking for how many records match, you'd just increment your own counter, rather than logging the index for each match.

Compare two arrays

I have two arrays:
array1=[1,2,3,4,5,6,7,8,9,10,11]
array2=[1,2]
I want to compare weather elements in "array2" is present in "array1" or not.
If yes then I need to run a function, otherwise exit.
How to do it?
I have get the common items like this:-
NSMutableSet *idSet=[NSMutableSet setWithArray:Array1];
[idSet intersectSet:[NSSet setWithArray:Array2]];
NSArray *Common_array=[idSet allObjects];
in common array you can get the same object that are present in both array and is 0 object in
Common_array than in both array there is none on object that are same.
What about enumerating over array1?
Something along the lines of
NSArray *array1 = ...;
NSArray *array2 = ...;
[array1 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([array2 containsObject: obj]) {
// Run the function you wanted to
}
}];
An easy logic way to do this would be a for loop:
for(int a = 0; a < array1.count; a++) {
for(int b = 0; b < array2.count; b++) {
if([[array1 objectAtIndex:a] isEqualToString:[array2 objectAtIndex:b]]) {
//do something here
}
}
}

How to get index in an NSArray?

NSMutableArray*array = [[NSMutableArray alloc]init];
NSArray*Somearray = [NSArray arrayWithObjects:1st Object,2ndObject,3rd Object,4th object,5th Object,nil];
In the above array 1st Object,2ndObject,3rd Object,4th object,5th Object having val,content,conclusion in each index.
for(int i=0;i<[Somearray count];i++)
{
______________
Here the code is there to give each index ,that is having val,content,conclusion ..
After that val,content,conclusion in each index will be add to Dict..
____________
NSDictionary *Dict = [NSDictionary dictionaryWithObjectsAndKeys:val,#"val",content,#"content",conclusion,#"conclusion",nil];
//Each time adding dictionary into array;
[array addObject:Dict];
}
The above Dictionary is in for loop and the keyvalue pairs will be add 5 times(Somearray Count).Now array is having in
array = [{val="1.1 this is first one",content="This is the content of 0th index",conclusion="this is the conclusion of 0th index"},{val="1.2 this is first one",content="This is the content of 1st index",conclusion="this is the conclusion of 1st index"},____,____,______,{val="1.5 this is first one",content="This is the content of 4th index",conclusion="this is the conclusion of 4th index"},nil];
Now i am having NSString*string = #"1.5";
Now i need the index where val is having 1.5 in it.How to send the str in to array to find the the index.
Can anyone share the code please.
Thanks in advance.
Use method indexOfObject
int inx= [array indexOfObject:#"1.5"];
For Find index particular key value.
int inx;
for (int i=0; i<[array count]; i++) {
if ([[[array objectAtIndex:i] allKeys] containsObject:#"val"]) {
inx=i;
break;
}
}
The method you are looking for is -[NSArray indexOfObjectPassingTest:]. You would use it like this:
NSUInteger i = [array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[id objectForKey:#"val"] rangeOfString:#"1.5"].location != NSNotFound;
}];
If you just want to check that val starts with "1.5" you would use hasPrefix: instead.
Try this -
NSArray *valArray = [array valueForKey:#"val"];
int index = [valArray indexOfObject:#"1.5"];
Appended answer given by Mandeep, to show you the magic of key value coding ;)
NSUInteger idx = UINT_MAX;
NSCharacterSet* spaceSet = [NSCharacterSet whitespaceCharacterSet];
for(int i=0,i_l=[Yourarray count];i<i_l;i++) {
NSString* s_prime = [[Yourarray objectAtIndex:i] valueForKey:#"val"];
if ([s_prime length] < 4) {
continue;
}
NSString *subString = [[s_prime substringToIndex:4] stringByTrimmingCharactersInSet:spaceSet];
// NSLog(#"index %#",s);
if ([subString isEqualToString:secretNumber]){
idx = i;
break;
}
}
if (idx != UINT_MAX) {
// NSLog(#"Found at index: %d",idx);
} else {
// NSLog(#"Not found");
}

How to get indices of NSArray using something like indexOfObject?

I can use [NSArray indexOfObject: NSString] to get an index of my search for 1 item. But what can I use or do to get an array of returned indices from my search?
thanks
To get multiple indices, you can use indexesOfObjectsPassingTest::
// a single element to search for
id target;
// multiple elements to search for
NSArray *targets;
...
// every index of the repeating element 'target'
NSIndexSet *targetIndices = [array indexesOfObjectsPassingTest:^ BOOL (id obj, NSUInteger idx, BOOL *stop) {
return [obj isEqual:target];
}];
// every index of every element of 'targets'
NSIndexSet *targetsIndices = [array indexesOfObjectsPassingTest:^ BOOL (id obj, NSUInteger idx, BOOL *stop) {
return [targets containsObject:obj];
}];
Support for blocks were added in iOS 4. If you need to support earlier versions of iOS, indexesOfObjectsPassingTest: isn't an option. Instead, you can use indexOfObject:inRange: to roll your own method:
#interface NSArray (indexesOfObject)
-(NSIndexSet *)indexesOfObject:(id)target;
#end
#implementation NSArray (indexesOfObject)
-(NSIndexSet *)indexesOfObject:(id)target {
NSRange range = NSMakeRange(0, [self count]);
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
NSUInteger idx;
while (range.length && NSNotFound != (idx = [self indexOfObject:target inRange:range])) {
[indexes addIndex: idx];
range.length -= idx + 1 - range.location;
range.location = idx + 1;
}
return [indexes autorelease];
}
#end
If you don't have access to indexOfObjectsPassingTest, as #outis recommends, you could use indexOfObject:inRange: and loop over the results, updating the range to start after the last result finished, and updating the results into your own NSIndexSet, or NSMutableArray, etc.

get the array index in for statement in objective-c

I am stuck in a stupid mess...
I want to get not only the value of an array but also the index of the values.
In PHP it's simple: foreach($array as $key->$value) Here $key will contain the index value.
Isn't there a similar approach in objective c?
How else could I achieve this?
Please help! :((
Arrays not like in php are numbered 0-size of array. I guess you talking about dictionary's. If so you can get array of key with [dict allKeys].
so something like this should work:
for(id key in [dict allKeys]){
id value = [dict objectForKey:key];
}
If you're on iOS4 you can do
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSLog(#"%# is at index %u", obj, idx);
}];
on iOS 3.x you can do
NSUInteger idx = 0;
for (id obj in array)
{
NSLog(#"%# is at index %u", obj, idx);
idx++
}
for (i=0;i<array.count;i++)
{
NSLog(#"Index=%d , Value=%#",i,[array objectAtIndex:i]);
}
Use this its simpler...
hAPPY cODING...
I'm unable to test it, but I think I did do something similar the other night. From this wiki it looks like you can do something like
for(id key in d) {
NSObject *obj = [d objectForKey:key]; // We use the (unique) key to access the (possibly non-unique) object.
NSLog(#"%#", obj);
}
int arraySize = array.count;
// No need to calculate count/size always
for (int i=0; i<arraySize; i++)
{
NSLog(#"Index=%d , Value=%#",i,[array objectAtIndex:i]);
}