Sort an NSMutableArray / Dictionary with several objects - iphone

I am having a problem that I think I am overcomplicating.
I need to make either an NSMutableArray or NSMutableDictionary. I am going to be adding at least two objects like below:
NSMutableArray *results = [[NSMutableArray alloc] init];
[results addObject: [[NSMutableArray alloc] initWithObjects: [NSNumber numberWithInteger:myValue01], #"valueLabel01", nil]];
This gives me the array I need but after all the objects are added I need to be able to sort the array by the first column (the integers - myValues). I know how to sort when there is a key, but I am not sure how to add a key or if there is another way to sort the array.
I may be adding more objects to the array later on.

Quick reference to another great answer for this question:
How to sort NSMutableArray using sortedArrayUsingDescriptors?
NSSortDescriptors can be your best friend in these situations :)

What you have done here is create a list with two elements: [NSNumber numberWithInteger:myValue01] and #"valueLabel01". It seems to me that you wanted to keep records, each with a number and a string? You should first make a class that will contain the number and the string, and then think about sorting.

Doesn't the sortedArrayUsingComparator: method work for you? Something like:
- (NSArray *)sortedArray {
return [results sortedArrayUsingComparator:(NSComparator)^(id obj1, id obj2)
{
NSNumber *number1 = [obj1 objectAtIndex:0];
NSNumber *number2 = [obj2 objectAtIndex:0];
return [number1 compare:number2]; }];
}

Related

Setting flags for elements in NSMutableArray

I have an NSMutableArray of elements and I want to be able to conditionally set custom flags for some of the elements. For example an error count for certain elements if they return an error. If the count is more than 3, I would like to delete this element from an array.
What would be the best way to implement such behaviour?
A few options:
Have a separate array holding your counter for each object. When deleting one from your original array, remember to delete it's corresponding counter object.
Create a small class that contains an int value and whatever other object you are storing in the array, and populate your NSMutableArray with that object. You will then have your object and the error counter on the same place
Edit: The second option is the most scalable one, if you ever want to add more flags or whatever to it.
You would be better off creating a mutable array filled with mutable dictionaries. This would allow you have two keys corresponding to each index in the array:
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"some text, or what ever you want to store",#"body",
[NSNumber numberWithUnsignedInteger:0],#"errorCount",
nil];
[myMutableArray addObject:mutableDictionary];
And then here is a basic example of how to increment the error count for a specific item in the array:
- (void)errorInArray:(NSUInteger)idx
{
if ([[[myMutableArray objectAtIndex:idx] objectForKey:#"errorCount"] unsignedIntegerValue] == 2) {
[myMutableArray removeObjectAtIndex:idx];
}else{
NSUInteger temp = [[[myMutableArray objectAtIndex:idx] objectForKey:#"errorCount"] unsignedIntegerValue];
temp ++;
[[myMutableArray objectAtIndex:idx] setObject:[NSNumber numberWithUnsignedInteger:temp] forKey:#"errorCount"];
}
}
As alluded above, no need for custom object creation necessarily:
Creating a mutable array, creating a dictionary with objects/keys and adding said dictionary to the array:
NSMutableArray *myArray = [[NSMutableArray alloc] init] autorelease];
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"John Doe", #"elementName",
[NSNumber numberWithInt:0], #"errorCount",
nil];
[myArray addObject:myDictionary];

Getting an NSArray of a single attribute from an NSArray

I am facing a very regular scenario.
I have an NSArray which has object of a custom type, say Person. The Person class has the attributes: firstName, lastName and age.
How can I get an NSArray containing only one attribute from the NSArray having Person objects?
Something like:
NSArray *people;
NSArray *firstNames = [people getArrayOfAttribute:#"firstName" andType:Person.Class]
I have a solution of writing a for loop and fill in the firstNames array but I don't want to do that.
NSArray will handle this for you using KVC
NSArray *people ...;
NSArray *firstName = [people valueForKey:#"firstName"];
This will give you an array of the firstName values from each entry in the array
Check out the filterUsingPredicate: method in NSMutableArray, basically you create a NSPredicate object that will define how the array will be filtered.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-CJBDBHCB
This guide will give you an overview, and has a section for dealing with arrays.
You can also use block based enumeration:
NSArray *people; // assumably has a bunch of people
NSMutableArray *firstNames = [NSMutableArray array];
[people enumerateObjectsUsingBlock:
^(id obj, NSUInteger idx, BOOL*flag){
// filter however you want...
[firstNames addObject:[Person firstName]];
}];
The benefit is it is fast and efficient if you have a bunch of people...

iPhone: How to convert normal NSArray into an NSArray containing NSNumber values?

In my iPhone app, I am using an array which contains the values like shown below:
A:{
1000,
2000,
-1000,
4000
}
Now I want to convert this to the array shown below.
NSArray *A = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:1000],[NSNumber numberWithInt:2000],[NSNumber numberWithInt:-1000],[NSNumber numberWithInt:4000],nil];
How can I do that?
Edit:
Also I cannot use the value of Array A:{1000,2000,-1000,4000} to directly pass it into the NSNumber numberWithInt method, because it takes these values as NSString and not integers.
regarding to another question I saw from you I'm guessing those values are NSStrings
then use something like this.
NSMutableArray *array = [NSMutableArray array];
for (NSString *numberString in numberStringArray) {
[array addObject:[NSNumber numberWithInteger:[numberString integerValue]]];
}
and to be honest I think you should invest more time for the basics before you try to make use of core-plot

Creating a Two-Dimensional Array with Concrete Positions

I need to create a custom array:
In php I would define as follows:
$myarray[100][80] = 1;
But I don't know how to do it in objective-c...
I don't need an array [0][0],[0][1],[0][2], ... I only need concrete positions in this array [80][12], [147][444], [46][9823746],...
The content of these positions always will be = 1;
for this you would use a dictionary rather than an array as they are always 0,1,2 keyed so something along the lines of:
NSNumber *one = [NSNumber numberWithInt:1];
NSString *key = #"80,12";
NSDictionary *items = [NSDictionary dictionaryWithObject:one forKey:key];
Then to pull them out again you would use the objectForKey: method.
You cannot put ints directly into arrays or dictionaries that's why it is wrapped in the NSNumber object. To access the int after getting the NSNumber out of the dictionary you would use something like:
NSNumber tempNum = [items objectForKey:key];
int i = tempNum.intValue;
See the docs here for a full explanation of the NSDictionary class. Hope this helps...
I an not a PHP master but I believe in php arrays are not real arrays they are hash tables right?
Anyway, I think you are looking for NSDictionary or NSMutableDictionary class.
That looks more like a bitset than an array.
Allocating so many cells for that seems useless, so maybe you could revert the problem, and store the positions in an array.
Well in objective c we can use NSMutableArray to define 2-D arrays.
See the following code, it might help you
NSMutableArray *row = [[NSMutableArray alloc] initWithObjects:#"1", #"2", nil];
NSMutableArray *col = [[NSMutableArray alloc] init];
[col addObject:row];
NSString *obj = [[col objectAtIndex:0] objectAtIndex:0];
NSLog(#"%#", obj);

iPhone - Merge keys in a NSArray (Objective-C)

I'm having troubles with arrays and keys... I have an array from my database:
NSArray *elementArray = [[[menuArray valueForKey:#"meals"] valueForKey:#"recipe"] valueForKey:#"elements"]
The problem here is that I would like all my elements of all my meals of all my menus in an array such that:
[elementArray objectAtIndex:0] = my first element
etc...
In the example above, the elements are separated by the keys.
How can I get that?
Hope it's clear enough...
Thanks
From your code snippet, it is not clear to me exactly how your data is structured, but I think it's analogous to having an NSDictionary (called aDictionary) of NSArray and wanting to combine all the NSArray into one. If this is the case, then:
NSMutableArray *resultArray = [[[NSMutableArray alloc] init] autorelease];
for (id dictionaryKey in aDictionary) {
[resultArray addObjectsFromArray:[aDictionary objectForKey:dictionaryKey]];
}
return [NSArray arrayWithArray:resultArray];
(This code has not been tested.)