How to get index in an NSArray? - iphone

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");
}

Related

Sort NSArray for a specific order

I have an NSArray of custom objects.
Each object contains one integer value for ex. 1,2,3,4
Now I want to sort Array like below
9 7 5 3 1 2 4 6 8
Could some one help me?
Here is your answer.
Hope your first array is in sorted order (ascending) if not then you need to sort it first.
NSMutableArray *myArray = [NSMutableArray array];
//Populate your array with custom objects. I had created my own which contain an integer type property.
[myArray addObject:[[myObject alloc] initWithId:11 objectName:#"K"]];
[myArray addObject:[[myObject alloc] initWithId:3 objectName:#"C"]];
[myArray addObject:[[myObject alloc] initWithId:4 objectName:#"D"]];
....
...
.... and so on
then sort it in Ascending order. You can do it Descending also but then you need to change the below logic little bit. I showing with Ascending order.
NSArray *tempArray = [myArray sortedArrayUsingComparator:^NSComparisonResult(myObject *obj1, myObject *obj2) {
if([obj1 objectId] > [obj2 objectId]) return NSOrderedDescending;
else if([obj1 objectId] < [obj2 objectId]) return NSOrderedAscending;
else return NSOrderedSame;
}];
Now sort them as per your requirement
NSMutableArray *finalArray = [NSMutableArray arrayWithArray:tempArray];
NSInteger totalObjects = [tempArray count];
NSInteger centerObjectIndex = totalObjects>>1;
__block NSInteger rightPosition = centerObjectIndex + 1;
__block NSInteger leftPosition = centerObjectIndex - 1;
__block BOOL toggle = NO;
[tempArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if(idx == 0) [finalArray replaceObjectAtIndex:centerObjectIndex withObject:obj];
else
{
if(toggle)
{
if(leftPosition >= 0)
{
[finalArray replaceObjectAtIndex:leftPosition withObject:obj];
leftPosition -= 1;
}
}
else
{
if(rightPosition < totalObjects)
{
[finalArray replaceObjectAtIndex:rightPosition withObject:obj];
rightPosition += 1;
}
}
toggle = !toggle;
}
}];
Here is the final step if your array contains an even numbers of objects
if(!(totalObjects % 2))
{
[finalArray removeObjectAtIndex:0];
[finalArray addObject:[tempArray objectAtIndex:totalObjects-1]];
}
Now you are at end. Your array named finalArray get sorted as per your requirement.

How to sort an array with alphanumeric values?

I have an array which contains strings like frame_10#3x.png , frame_5#3x.png,frame_19#3x.png etc.
So I want to sort this array according to the number after the underscore i.e. the correct sequence will be frame_5#3x.png,frame_10#3x.png,frame_19#3x.png.
I tried to use the following method but no result:
NSInteger firstNumSort(id str1, id str2, void *context) {
int num1 = [str1 integerValue];
int num2 = [str2 integerValue];
if (num1 < num2)
return NSOrderedAscending;
else if (num1 > num2)
return NSOrderedDescending;
return NSOrderedSame;
}
Please suggest how to do this sorting for array.
NSArray *sry_img = [[NSArray alloc] initWithObjects:#"frame_18#3x.png",#"frame_17#3x.png",#"frame_1222#3x.png",#"frame_10#3x.png",#"frame_3#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",#"frame_1#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",nil];
NSArray *sortedStrings = [sry_img sortedArrayUsingSelector:#selector(localizedStandardCompare:)];
NSLog(#"%#",sortedStrings);
Enjy .......
But
localizedStandardCompare:, added in 10.6, should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact behavior of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings.
you want to do something like:
NSArray *components1 = [str1 componentsSeparatedByString:#"_"];
NSArray *components2 = [str2 componentsSeparatedByString:#"_"];
NSString *number1String = [components1 objectAtIndex:([components1 count] - 1])];
NSString *number2String = [components2 objectAtIndex:([components2 count] - 1])];
return [number1String compare:number2String];
I am not sure if my solution is the best possible approach but it can solve your problem for the time being :) .
1) First I have written a function to get the numbers before # character in your string and then I implemented simple SELECTION SORT algo to sort the array using this functions.
- (NSString*)getSubStringForString:(NSString*)value {
// First we will cut the frame_ string
NSMutableString *trimmedString = [NSMutableString stringWithString:[value substringWithRange:NSMakeRange(6, [value length]-6)]];
// New String to contain the numbers
NSMutableString *newString = [[NSMutableString alloc] init];
for (int i = 0; i < [trimmedString length] ; i++) {
NSString *singleChar = [trimmedString substringWithRange:NSMakeRange(i, 1)];
if (![singleChar isEqualToString:#"#"]) {
[newString appendString:singleChar];
} else {
break;
}
}
return newString;
}
This is the selection Implementation of the algo for sorting. The main logic is in the for loop. You can copy the code in viewDidLoad method to test.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"frame_10#3x.png",#"frame_5#3x.png",
#"frame_3#3x.png", #"frame_19#3x.png",
nil];
NSLog(#"Values before Sort: %#", array);
int iPos;
int iMin;
for (iPos = 0; iPos < [array count]; iPos++)
{
iMin = iPos;
for (int i = iPos+1; i < [array count]; i++)
{
if ([[self getSubStringForString:[array objectAtIndex:i]] intValue] >
[[self getSubStringForString:[array objectAtIndex:iMin]] intValue]) {
iMin = i;
}
}
if ( iMin != iPos )
{
NSString *tempValue = [array objectAtIndex:iPos];
[array replaceObjectAtIndex:iPos withObject:[array objectAtIndex:iMin]];
[array replaceObjectAtIndex:iMin withObject:tempValue];
}
}
NSLog(#"Sorted Values: %#", array);
I hope that it can atleast keep you going. :)
You can try this-
NSString *str1 = [[[[str1 componentsSeparatedByString:#"frame_"] objectAtIndex:1] componentsSeparatedByString:#"#3x.png"] objectAtIndex:0];
int num1 = [str1 integerValue];

How to add array values using NSMutableArray in iPHone?

I have the data into the mutable array and the value of array is,
{ "20", "40", "50","60", "70"}.
I have stored the string values into the array.
Now i want to total value of the array. Result is : 240
Thanks!
NSInteger value = 0;
for (String *digit in myArray) {
value += [digit intValue];
}
int total=0;
for(NSString *currentString in myArray){
total +=[currentString intValue];
}
NSLog(#"Sum:%d",total);
This adds all values:
__block NSInteger sum = 0;
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
sum += [obj intValue];
}];
You can do as follows:
int totalSum = 0;
NSmutableArray *arrayData = [[NSmutableArray alloc] init];
[arrayData addObject:#"20"];
[arrayData addObject:#"40"];
[arrayData addObject:#"50"];
[arrayData addObject:#"60"];
[arrayData addObject:#"70"];
for(int i=0; i<[arrayData count];i++)
{
totalSum = totalSum + [[arrayData objectAtIndex:i] intValue];
}
NSLog(#"Total:%d",totalSum);
Please let me know if you have any question.
How about the most elegant solution using key-value Collection aggregators:
NSNumber *sum = [myArray valueForKeyPath:#"#sum.self"];

get values form NSMutableArray from end to start

I want to take the values from NSMutableArray but want to read from last index to 1st index
thank you
for (id someObject in [someArray reverseObjectEnumerator])
{
//do your thing
}
2 other options:
Simple for-loop (surely not recommended):
for (int i = [array count]-1; i >= 0; ++i)
id value = [array objectAtIndex: i];
Block-based enumeration:
[array enumerateObjectsWithOptions: NSEnumerationReverse
usingBlock: ^(id obj, NSUInteger idx, BOOL *stop){
//do something
}];
Mark's answer is useful, but this form may be useful when you want to mutate the array:
while ([arr count]) {
id obj = [arr lastObject];
// use obj
[arr removeLastObject];
}

How to compare array element?

Suppose I have an array having elements "am","john","rosa","freedom". I want to compare these elements and result would be the word and the size of the longest word. I am using objective C.
There isn't a "built-in" way of doing this, however you can use NSArray's sortedArrayUsingSelector: and create a category on NSString to provide a lengthCompare: method.
// NSString+LengthCompare.h
#import NSString.h
#interface NSString (LengthComparison)
- (NSComparisonResult)lengthCompare:(NSString *)aString;
#end
// NSString+LengthCompare.m
#import NSString+LengthCompare.h
#implememtation NSString (LengthComparison)
- (NSComparisonResult)lengthCompare:(NSString *)aString
{
if ([self length] < [aString length]) {
return NSOrderedAscending;
} else if ([self length] > [aString length]) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
#end
Now you can sort an of strings in ascending order using lengthCompare:
NSArray *array = [NSArray arrayWithObjects: #"am", #"john", #"rosa", #"freedom", nil];
NSArray *arraySortedByStringLength = [array sortedArrayUsingSelector:#selector(lengthCompare:)];
NString *shortestWord = [[arraySortedByStringLength objectAtIndex:0] retain];
NSLog(#"shortest word, %# has length %d", shortestWord, [shortestWord length];
[shortestWord release];
NString *longestWord = [[arraySortedByStringLength lastObject] retain];
NSLog(#"Longest word, %# has length %d", longestWord, [longestWord length];
[longestWord release];
Sounds like a classical logic exercise or is it something I miss in your question ?
int longestWordIndex = 0;
NSUInteger longestWordSize = 0;
for (int i=0 ; i<[nameArray count] ; i++) {
NSString* element = (NSString*)[nameArray objectAtindex:i];
if([element lenght] > longestWordSize) {
longestWordSize = [element lenght];
longestWordIndex = i;
}
}
NSLog("Longest word is %# with size of :%d", [nameArray objectAtIndex:longestWordIndex], longestWordSize);
I'll add one more approach to the two above -- use a block to do the body of your iteration.
__block NSUInteger longestWordSize = -1; // Make sure at least one object will be longer.
__block NSUInteger longestWordIndex;
[nameArray enumerateObjectsUsingBlock:^(id currentWord, NSUInteger index, BOOL *stop) {
if ([currentWord length] > longestWordSize) {
longestWordSize = [currentWord length];
longestWordIndex = index;
}
}];
NSLog("Longest word is %# with size of :%d", [nameArray objectAtIndex:longestWordIndex], longestWordSize);
Edit: The max and index have to be of storage type __block so they can be changed from inside the block.