Reputation: 1740
I have NSDictionaries in NSArray just like below.
array(dictionary("user":1, "p1":1), dictionary("user":2, "p1":3), dictionary("user":1, "p1":5), dictionary("user":2, "p1":7))
And I want to turn this array into dictionary like below.
NSArray *u1 = [NSArray arrayWithObjects:@"1", @"5", nil];
NSArray *u2 = [NSArray arrayWithObjects:@"3", @"7", nil];
keys = [NSArray arrayWithObjects:@"u1", @"u2", nil];
points = [NSDictionary dictionaryWithObjectsAndKeys:u1, @"u1", u2, @"u2", nil];
How can I do that? I am lost, can you guys please help me?
Upvotes: 0
Views: 472
Reputation: 53010
What have you tried?
Here is some code typed directly into the answer, so it has not be tested:
You haven't given a name for your original array, so let's assume it is:
NSArray *originalArray;
We need a mutable dictionary to store the result:
NSMutableDictionary *points = [NSMutableDictionary new];
Now we need to process every element in the original array and it is a dictionary:
for(NSDictionary *item in originalArray)
{
Get the current entry in points
array that matches item
. You don't give types for your entries, so we'll use id
:
id currentUser = [item objectForKey:@"user"];
NSMutableArray *currentValues = [points objectForKey:currentUser];
If this is the first occurrence of currentUser
then currentValues
will be nil
, and we need to create an array for the p1
value and add it to points
:
if (currentValues == nil)
[points addObject:[NSMutableArray arrayWithObject:[item objectForKey:@"p1"]
forKey:currentUser
]
]
Otherwise we just add the p1
value to the array:
else
[currentValues setObject:[item objectForKey:@"p1"]];
close out the loop and get the keys:
}
NSArray *keys = [points allKeys];
Now if you're using Xcode 4.5 you can use modern syntax for some of that:
NSMutableDictionary *points = [NSMutableDictionary new];
for(NSDictionary *item in originalArray)
{
id currentUser = item[@"user"];
NSMutableArray *currentValues = points[currentUser];
if (currentValues == nil)
points[currentUser] = [NSMutableArray arrayWithObject:item[@"p1"];
else
[currentValues addObject:item[@"p1"]];
}
NSArray *keys = [points allKeys];
HTH
Upvotes: 1
Reputation: 438467
Tons of approaches. Here's another:
NSArray *originalArray = @[
@{@"user":@"u1", @"p1":@"1"},
@{@"user":@"u2", @"p1":@"3"},
@{@"user":@"u1", @"p1":@"5"},
@{@"user":@"u2", @"p1":@"7"}
];
NSLog(@"originalArray = %@", originalArray);
NSMutableDictionary *results = [NSMutableDictionary dictionary];
for (NSDictionary *dictionary in originalArray) {
NSString *user = dictionary[@"user"];
NSString *p1 = dictionary[@"p1"];
if (!results[user])
results[user] = [NSMutableArray array];
[results[user] addObject:p1];
}
NSLog(@"results = %@", results);
That takes:
originalArray = (
{
p1 = 1;
user = u1;
},
{
p1 = 3;
user = u2;
},
{
p1 = 5;
user = u1;
},
{
p1 = 7;
user = u2;
}
)
And gives
results = {
u1 = (
1,
5
);
u2 = (
3,
7
);
}
Upvotes: 0
Reputation: 540125
Another possible solution (works with an arbitrary number of users):
NSArray *orig = @[
@{@"user" : @"1", @"p1" : @"1"},
@{@"user" : @"2", @"p1" : @"3"},
@{@"user" : @"1", @"p1" : @"5"},
@{@"user" : @"2", @"p1" : @"7"},
];
// Create set of all users (without duplicates)
NSSet *users = [NSSet setWithArray:[orig valueForKey:@"user"]];
NSMutableDictionary *points = [NSMutableDictionary dictionary];
for (NSString *user in users) {
// newKey = "u" + username, e.g. "u1" or "u2":
NSString *newKey = [@"u" stringByAppendingString:user];
// newValue = array of "p1" values of the current user:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"user == %@", user];
NSArray *newValue = [[orig filteredArrayUsingPredicate:pred] valueForKey:@"p1"];
// Add to dictionary:
[points setObject:newValue forKey:newKey];
}
NSLog(@"%@", points);
Output:
{
u1 = (
1,
5
);
u2 = (
3,
7
);
}
And the keys can be obtained by
NSArray *keys = [points allKeys];
Upvotes: 0
Reputation: 46563
You can do, like this (code not tested)
NSMutableArray *keys=[NSMutableArray new];
NSMutableArray *u1=[NSMutableArray new];
NSMutableArray *u2=[NSMutableArray new];
NSMutableDictionary *points=[NSMutableDictionary new];
for (id dict in array){
NSString *user=[dict objectForKey:@"user"];
NSString *p1=[dict objectForKey:@"p1"];
[keys addObject:[NSString stringWithFormat:@"%@",user]];
if( [user isEqualToString:@"1"] ){
[u1 addObject:user];
}
else{
[u2 addObject:user];
}
}
points=[NSDictionary dictionaryWithObjectsAndKeys:u1,@"u1",u2, @"u2", nil];
Upvotes: 0
Reputation: 172
Couldn't you just iterate over your original array, asking each dictionary if the object for key "user" is 1, and if so, copy the object into a new array at index 0? Or if your user numbers are in counting order, maybe even have the index number equal the user number. Then repeat for "user" = 2, etc. Then make a dictionary so that each key/object pair is created by keys from the keys array (keys[i]) and objects from your new array (objects[i]).
Upvotes: 2