sorting 2D arrays in Objective C - objective-c

I'm stuck with sorting 2D arrays in objective c. I have a 2D array which I made from two string arrays.
NSArray *totalRatings = [NSArray arrayWithObjects:namesArray,ratingsArray,nil];
I've pulled the values using:
for (int i=0; i<2; i++) {
for (int j=0; j<5; j++) {
NSString *strings = [[totalRatings objectAtIndex:i] objectAtIndex:j];
NSLog(#"i=%i, j=%i, = %# \n",i,j,strings);
}
}
Firstly, I wonder whether there is a more elegant method for working with the length of the totalRatings array. Secondly, here is what the totalRatings array contains:
Person 1, 12
Person 2, 5
Person 3, 9
Person 4, 10
Person 7, 2
Since these are all strings, how can these be sorted? I'm looking for:
Person 1, 12
Person 4, 10
Person 3, 9
Person 2, 5
Person 7, 2
I'd appreciate any help you can provide.

You may want to use a dictionary to deal with this data, instead of two distinct arrays.
Instead of what you have now, why don't you put the record for each person on a dictionary:
NSArray *totalRatings = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 1", #"name", [NSNumber numberWithInt:12], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 2", #"name", [NSNumber numberWithInt:5], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 3", #"name", [NSNumber numberWithInt:9], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 4", #"name", [NSNumber numberWithInt:10], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 7", #"name", [NSNumber numberWithInt:2], #"rating", nil],
nil];
NSArray *sortedArray = [totalRatings sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"rating" ascending:NO]]];

Related

formatting dictionary values

I am needing to store values in a dictionary in the following format:
{ "UserId": 123,
"UserType": "blue",
"UserActs": [{
"ActId": 3,
"Time": 1
}, {
"ActId": 1,
"Time": 6
}]
}
I know I'll need a dictionary for the intitial values and a nested one for the UserActs but I am unsure how to store seperate values for the same keys "ActId" and "Time". How would I go about adding them in the dictionary following this format?
This is the old, long winded, way of creating that dictionary (there is a new syntax, using Objective-C literals, however they are not mutable, so I chose this method):
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:123] forKey:#"UserId"];
[dict setObject:#"blue" forKey:#"UserType"];
NSMutableArray *acts = [[NSMutableArray alloc] init];
[acts addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:3], #"ActId",
[NSNumber numberWithInt:1], #"Time",
nil]];
[acts addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], #"ActId",
[NSNumber numberWithInt:6], #"Time",
nil]];
[dict setObject:acts forKey:#"UserActs"];
You can also use the shorthand for arrays and dictionaries
NSDictionary * dictionary = #{ #"UserId": #123,
#"UserType": #"blue",
#"UserActs": #[#{
#"ActId": #3,
#"Time": #1
}, #{
#"ActId": #1,
#"Time": #6
}]
};

Finding the minimum value using KVC across n-keys

Stuck on KVCs in Obj-C again.
I am wanting to use KVC to find the minimum value across multiple keys.
Consider the following array:
NSArray *data = [[NSArray alloc] initWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:2.0], #"a", [NSNumber numberWithFloat:5.0], #"b", [NSNumber numberWithFloat:4.0], #"c", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:3.0], #"a", [NSNumber numberWithFloat:1.0], #"b", [NSNumber numberWithFloat:1.5], #"c", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:9.0], #"a", [NSNumber numberWithFloat:7.0], #"b", [NSNumber numberWithFloat:6.0], #"c", nil],
nil];
I can find the minimum value for 'a', 'b', or 'c' easily with:
float minKeyA = [[data valueForKeyPath:#"#min.a"] floatValue]; // value: 2.0
float minKeyB = [[data valueForKeyPath:#"#min.b"] floatValue]; // value: 1.0
float minKeyC = [[data valueForKeyPath:#"#min.c"] floatValue]; // value: 1.5
What I am wanting to achieve is to take a NSSet or NSArray of keys and find the minimum value across the pool of those keys.
NSSet *keySet1 = [NSSet setWithObjects:#"a", #"b", nil];
// use to find absolute minimum value across keys 'a' and 'b' --> desired value 1.0
NSSet *keySet2 = [NSSet setWithObjects:#"a", #"c", nil];
// use to find absolute minimum value across keys 'a' and 'c' --> desired value 1.5
NSSet *keySet3 = [NSSet setWithObjects:#"a", #"b", #"c", nil];
// use to find absolute minimum value across keys 'a', 'b', and 'c' --> desired value 1.0
Appreciate any pointers :)
A naive solution would be to first find the minimum value for each key and then find the minimum among those minimum values in a second step.
NSMutableSet *localMinima = [NSMutableSet setWithCapacity:[keySet1 count]];
for (NSString *key in keySet1) {
NSString *keyPath = [NSString stringWithFormat:#"#min.%#", key];
NSNumber *localMin = [data valueForKeyPath:keyPath];
[localMinima addObject:localMin];
}
NSNumber *globalMin = [localMinima valueForKeyPath:#"#min.self"];

Whats the best way to convert an NSString to an NSInteger based on an array of values?

I want to convert characters into integers based on predetermined values, for example:
a = 0
b = 1
c = 2
d = 3
etc...
Right now I'm doing it with an If/Else If, I just want to know if there is a faster/better way I should be doing it because the list of conversions may get quite long.
Here's what I'm using now:
-(NSInteger)ConvertToInt:(NSString *)thestring {
NSInteger theint;
if([thestring isEqualToString:#"a"] == YES){
theint = 0;
} else if ([thestring isEqualToString:#"b"] == YES){
theint = 1;
} //etc...
return theint;
}
This works fine, but as I said, if it makes more sense can I create an array with all the key/values then just run through that to return the integers?
Please provide examples as I'm a beginner with Objective C/iOS. I come from Web languages.
Thanks!
EDIT: Thanks for the help everyone. I used taskinoors answer but I replaced the NSDictionary which was giving error messages with this:
NSDictionary *dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:0], #"a",
[NSNumber numberWithInt:1], #"b",
[NSNumber numberWithInt:2], #"c", nil];
unichar ch = [thestring characterAtIndex:0];
theint = ch - 'a';
Note that, 'a' with a single quote is character a, not string "a".
If the values are not regular like your example then you can store all predefined values into a dictionary. For example:
"a" = 5;
"b" = 1;
"c" = 102;
NSArray *values = [NSArray arrayWithObjects:[NSNumber numberWithInt:5],
[NSNumber numberWithInt:1], [NSNumber numberWithInt:102], nil];
NSArray *keys = [NSArray arrayWithObjects:#"a", #"b", #"c", nil];
NSDictionary *dic = [NSDictionary dictionaryWithObjects:values forKeys:keys];
theint = [[dic valueForKey:thestring] intValue];
If you wanted to keep some flexibility in what strings map to what integers, and your integers run from 0 to n-1 where you have n unique items in the array, you could do something like this:
-(NSInteger)ConvertToInt:(NSString *)thestring {
NSArray *arr = [NSArray arrayWithObjects:#"a", #"b", #"c", #"d", nil];
NSInteger theint = [arr indexOfObject:thestring];
return theint;
}
Now this will build the array each time, which would be very inefficient, the optimal way would be to build the array once in your class, and then just use a reference to that array with the indexOfObject method call.

how to define 2x2 array in ios?

how to define 2x2 or 3X.. array in ios?
like this
[name=john , age=21 , num=1]
[name=max , age=25 , num=2]
[name=petter , age=22 , num=3]
with columns
in NSMutableArray you can only add rows with objects;
i want this array[][]
Looking at your example, I wouldn't do it with arrays, or not just arrays. I'd have an array of dictionaries or an array of custom objects with the properties name, age and num. With dictionaries:
NSArray* theArray = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
#"john", #"name",
[NSNumber numberWithInt: 21], #"age",
[NSNumber numberWithInt: 1], #"num",
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
#"max", #"name",
[NSNumber numberWithInt: 25], #"age",
[NSNumber numberWithInt: 2], #"num",
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
#"petter", #"name",
[NSNumber numberWithInt: 22], #"age",
[NSNumber numberWithInt: 3], #"num",
nil],
nil];
How to declare a two dimensional array of string type in Objective-C? might give you an idea
So many ways ...
NSMutableArray *array = [[NSMutableArray alloc] init];
NSMutableDictionary *person = [[[NSMutableDictionary alloc] init] autorelease];
[person setObject:#"john" forKey:#"name"];
[person setObject:[NSNumber numberWithInt:21] forKey:#"age"];
...
[array addObject:person];
... or create your custom class, which does hold all person data, or struct, or ... Depends on your goal.
It looks like you should be create a proper data storage class to store this in, rather than a dictionary or something like that.
e.g.
#interface Person : NSObject {
}
#property (nonatomic, copy) NSString* Name;
#property int age;
#property int num;
#end
Then create your person instances and store them in an array. You may wich to create some connivence methods first. e.g.
[[NSArray arrayWithObjects:[Person personWithName:#"Bob",Age:1 Num:3],
[Person personWithName:#"Bob",Age:1 Num:3],
[Person personWithName:#"Bob",Age:1 Num:3],nil];
Its much clearer.

hash of array in objective-c, how?

How is a hash of integer array can be represented in objective-c? Here is the ruby hash as an example:
hi_scores = { "John" => [1, 1000],
"Mary" => [2, 8000],
"Bob" => [5, 2000] }
such that can be accessed by:
puts hi_scores["Mary"][1]
=> 8000
hopefully easy to serialize too. Thanks!
NSDictionary * highScores = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:1000], nil], #"John",
[NSArray arrayWithObjects:[NSNumber numberWithInt:2], [NSNumber numberWithInt:8000], nil], #"Mary",
[NSArray arrayWithObjects:[NSNumber numberWithInt:5], [NSNumber numberWithInt:2000], nil], #"Bob", nil];
NSLog(#"%#", [[highScores objectForKey:#"Mary"] objectAtIndex:1]);
You're looking for a data structure called a map / associative array.
Take a look at this question:
HashTables in Cocoa