I want to sort NSMutableArray which have NSInteger values inside. I tried to use this solution:
NSArray *sorted = [array sortedArrayUsingSelector:#selector(compare:)];
It almost worked, so i want to ask why not everything alright with it. Here is example of data:
not sorted = (
30,
42,
54,
6,
18
)
sorted = (
18,
30,
42,
54,
6
)
We can see that it sorted everything but 6 value which is at the end off array.
Why this could happened ?
Thank you.
Full method:
- (void) initialize{
NSInteger min = 30;
NSInteger interval = 12;
NSInteger count = floor(60/interval);
for (int i = 0; i < count; i++) {
[array addObject:[NSString stringWithFormat:#"%i",min]];
min +=interval;
if (min > 60)
min -= 60;
}
//DLog(#"not sorted = %#",minutes);
array = [[array sortedArrayUsingSelector:#selector(compare:)] mutableCopy];
//DLog(#"sorted = %#",minutes);
}
You are getting problem in above case because you are sorting string values not a NSNUMBER.
You have to use NSNumber to add objects of integer. Then do something like:
NSMutableArray *array = [[NSMutableArray alloc ] initWithObjects:
[NSNumber numberWithInt:10],
[NSNumber numberWithInt:50],
[NSNumber numberWithInt:5],
[NSNumber numberWithInt:3],
nil];
NSLog(#"SORTED = %#",[array sortedArrayUsingSelector:#selector(compare:
)]);
This will give you a sorted array.
Related
I'm new to objective c. I am getting my data from an NSArray and want to return value according to some condition. My code is:
NSArray *myData;
NSNumber *day = 5;
myData = [NSArray arrayWithObjects: #"5", nil];
for (int i = 0; i < [myData count]; i++) {
if(day == myData[0]){
NSLog(#"date in valueForDay %# ", da );
return 3;
}
}
Above code doesn't execute my statements (NSLog and return one).
But if i statically compare day with any number it got executed. Like:
NSArray *myData;
NSNumber *day = 5;
myData = [NSArray arrayWithObjects: #"5", nil];
for (int i = 0; i < [myData count]; i++) {
if(day == 5){
NSLog(#"date in valueForDay %# ", da );
return 3;
}
}
can anyone please tell me where i'm doing wrong?
You have created array with string value not with number value. That's why object from your array is "5" which is not equal to integer 5. Make your array as number array.
myData = [NSArray arrayWithObjects: #5, nil];
Also instead of for loop you can simply use indexOfObject to check array having object or not.
NSInteger index = [myData indexOfObject: day];
if(index != NSNotFound) {
return 3;
}
You stored NSString in NSArray. And comparing with NSNumber. You have to add one line above if condition and change your condition.
NSString *myString = [day stringValue];
if([myString isEqualToString:myData[0]])
I have an array containing twenty items. I want to search through the array, comparing one item to the next one in the array, and then print the larger item. I have already sorted the array. I just want to compare the two items, check what the remainder is between the two values, and if it's greater than say, four, print the larger item.
NSArray* arr = [NSArray arrayWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:7],
[NSNumber numberWithInt:11],
nil
];
int len = [arr count];
for (int i=0; i < len-1; ++i) {
int num1 = [[arr objectAtIndex:i] intValue];
int num2 = [[arr objectAtIndex:i+1] intValue];
if ( num2-num1 > 4 ) {
NSLog(#"%d", num2);
}
}
--output:--
6
NSEnumerator *itemEnumerator = [theArray objectEnumerator];
YourClass *lastObject = [itemEnumerator nextObject];
YourClass *compareObject;
while( (compareObject = [itemEnumerator nextObject]) != nil)
{
if( /* place your condition here */ )
{
NSLog( … );
}
lastObject = compareObject;
}
Typped in Safari
I have NSArray1 = (1, 5, 2)
and NSArray2 = (1, 3, 5)
i want to array1 + array2 = (should return) = (2, 8, 7)
(in fact is it even possible to do this with NSArray)?
Heres a similar question
Adding two arrays together
(but this adds the values of the second array onto the end of the first array)
NSArray *a = [NSArray arrayWithObjects: #"1" ,#"2",#"3",nil];
NSArray *b = [NSArray arrayWithObjects: #"1" ,#"2",#"3",nil];
NSMutableArray *c = [[NSMutableArray alloc]init];
c = [a addObjectsFromArray:b];
// just a test code . . . .
If it's a C array, then just do
int newArray[3];
for (int i=0;i<3;i++)
newArray[i] = array1[i]+array2[i];
But if it's a NSArray with NSNumbers (You can't have primitives in NSArray), then just do
NSMutableArray *newArray = [NSMutableArray array];
for (int i=0;i<[array1 count];i++)
[newArray addObject:[NSNumber numberWithInt:[[array1 objectAtIndex:i] intValue]+[[array2 objectAtIndex:i] intValue]]];
//If you're using Mountain Lion, then you can use the following
//[newArray addObject:#([array1[i] intValue]+[array2[i] intValue])];
Edit:
If you have more than 1 array, then
int numArrays = 3;
NSArray *arrayOfNum = //An array of arrays that contains all the numbers
NSMutableArray *newArray = [NSMutableArray array]
for (int i=0;i<[array1 count];i++)
{
int total = 0;
for (int x=0;x<numArrays;x++)
total+=[arrayOfNum[x] intValue];
[newArray addObject:#(total)];
}
Let's say I want to populate NSarray with 50 integers. We know that NSarray accept only objects. So I have to do 50 times
NSNumber *num1 = [NSNumber numberWithInit:10];
NSNumber *num2 = [NSNumber numberWithInit:212];
......
NSNumber *num50 = [NSNumber numberWithInit:12];
Is there more elegant way to achieve that, beacause looks stupid 50 lines of code only for create number objects ?
try this...
NSMutableArray *array=[[NSMutableArray alloc]initWithCapacity:50 ];
for (int i=0; i<0; i++) {
NSNumber *number=[[NSNumber alloc] initWithInt:i];
[array addObject:number];
[number release];
}
//do anything with arrray and release the array later.
is this OK or you are seeking anything else.?
How about using NSMutableArray?
NSMutableArray* arr = [[NSMutableArray alloc] init];
int i = 0;
for(i=0; i<50; i++) {
NSNumber* num = [NSNumber numberWithInt:i]; // use i or random numbers
[arr addObject:num];
}
Your numbers do not seem to follow any particular pattern, so you might be better doing this by creating a C array first:
int myValues[] = { 10, 212, ..., 12 };
NSUInteger count = sizeof(myValues)/sizeof(int); // number of integers in myValues
// abstract the following into a function/method/category if doing more than once
NSMutableArray *objcValues = [NSMutableArray arrayWithCapacity:count];
for(NSUInteger ix = 0; ix < count; ix++)
[objcValues addObject:[NSNumber numberWithInt:myValues[ix]];
I have an array with a 14 strings. I want to display each of these 14 strings to the user without duplicates. The closest I got was creating an array of integers and shuffling their values, and then reading from the array of strings using one of the numbers from the int array as the index:
//appDelegate.randomRiddles is an array of integers that has integer values randomly
appDelegate.randomRiddlesCounter++;
NSNumber *index=[appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
int i = [index intValue];
while(i>[appDelegate.currentRiddlesContent count]){
appDelegate.randomRiddlesCounter++;
index=[appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
i = [index intValue];
}
hintText.text = [[appDelegate.currentRiddlesContent objectAtIndex:i] objectForKey:#"hint"];
questionText.text = [[appDelegate.currentRiddlesContent objectAtIndex:i] objectForKey:#"question"];
But my way is causing crashing and duplicates. Oh and each time I read a value from the strings array, that string is removed from the array making its count decrease by 1. So that complicates this a little bit.
Get the elements in your array like this:
int position = arc4random() % ([myArray count]);
This way even though count decreases by one, that is ok, as you will still get a valid next position value till there aren't any more posible values.
By "without duplicates" I assume you mean that you want to use each string in the array once before you use the same string again, not that you want to filter the array so it doesn't contain duplicate strings.
Here's a function that uses a Fisher-Yates shuffle:
/** #brief Takes an array and produces a shuffled array.
*
* The new array will contain retained references to
* the objects in the original array
*
* #param original The array containing the objects to shuffle.
* #return A new, autoreleased array with all of the objects of
* the original array but in a random order.
*/
NSArray *shuffledArrayFromArray(NSArray *original) {
NSMutableArray *shuffled = [NSMutableArray array];
NSUInteger count = [original count];
if (count > 0) {
[shuffled addObject:[original objectAtIndex:0]];
NSUInteger j;
for (NSUInteger i = 1; i < count; ++i) {
j = arc4random() % i; // simple but may have a modulo bias
[shuffled addObject:[shuffled objectAtIndex:j]];
[shuffled replaceObjectAtIndex:j
withObject:[original objectAtIndex:i]];
}
}
return shuffled; // still autoreleased
}
If you want to keep the relationship between the riddles, hints, and questions then I'd recommend using a NSDictionary to store each set of related strings rather than storing them in separate arrays.
This task is very easy using an NSMutableArray. In order to do this, simply remove a random element from the array, display it to the user.
Declare a mutable array as an instance variable
NSMutableArray * questions;
When the app launches, populate with values from myArray
questions = [[NSMutableArray alloc] initWithArray:myArray]];
Then, to get a random element from the array and remove it, do this:
int randomIndex = (arc4random() % [questions count]);
NSDictionary * anObj = [[[questions objectAtIndex:randomIndex] retain] autorelease];
[questions removeObjectAtIndex:randomIndex];
// do something with element
hintText.text = [anObj objectForKey:#"hint"];
questionText.text = [anObj objectForKey:#"question"];
No need to type that much. To shuffle an array, you just sort it with random comparator:
#include <stdlib.h>
NSInteger shuffleCmp(id a, id b, void* c)
{
return (arc4random() & 1) ? NSOrderedAscending : NSOrderedDescending;
}
NSArray* shuffled = [original sortedArrayUsingFunction:shuffleCmp context:0];
You could copy the array into an NSMutableArray and shuffle that. A simple demonstration of how to shuffle an array:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Original array, here initialised with 1..9
NSArray *arr = [NSArray arrayWithObjects:
[NSNumber numberWithInt: 1],
[NSNumber numberWithInt: 2],
[NSNumber numberWithInt: 3],
[NSNumber numberWithInt: 4],
[NSNumber numberWithInt: 5],
[NSNumber numberWithInt: 6],
[NSNumber numberWithInt: 7],
[NSNumber numberWithInt: 8],
[NSNumber numberWithInt: 9],
nil];
// Array that will be shuffled
NSMutableArray *shuffled = [NSMutableArray arrayWithArray: arr];
// Shuffle array
for (NSUInteger i = shuffled.count - 1; i > 0; i--)
{
NSUInteger index = rand() % i;
NSNumber *temp = [shuffled objectAtIndex: index];
[shuffled removeObjectAtIndex: index];
NSNumber *top = [shuffled lastObject];
[shuffled removeLastObject];
[shuffled insertObject: top atIndex: index];
[shuffled addObject: temp];
}
// Display shuffled array
for (NSNumber *num in shuffled)
{
NSLog(#"%#", num);
}
[pool drain];
return 0;
}
Note that all arrays and numbers here are autoreleased, but in your code you might have to take care of memory management.
If you don't have to keep the elements in the array, you can simplify that (see Oscar Gomez' answer too):
NSUInteger index = rand() % shuffled.count;
NSLog(#"%#", [shuffled objectAtIndex: index]);
[shuffled removeObjectAtIndex: index];
At the end, shuffled will be empty. You will have to change the loop conditions too:
for (NSUInteger i = 0; i < shuffled.count; i++)