Group element in NSMutableArray which contains object - ios

I have an NSMutableArray that contains an object of a class model in each position like this.
The class model contains 2 types of information, which we will call id and name.
So, in every location of my NSMutableArray I have an object that contains 2 information.
Then, in the first position of my NSMutableArray I have
{
id = 1;
name = "Dan"; //this is the first object in NSMutableArray
}
In the second position of NSMutableArray, I have:
{
id = 1;
name = "Luca";
}
In the third position
{
id = 2;
name = "Tom";
}
and so on..
Ok, my goal is to make the union of identical IDs between the various objects within the SNMutableArray but it's too difficult!
For example, if I have:
{
id = 1;
name = "Tom";
}
{
id = 1;
name = "Luca";
}
{
id = 2;
name = "Steve";
}
{
id = 2;
name = "Jhon";
}
{
id = 3;
name = "Andrew";
}
The goal is:
{
id = 1;
name = "Tom";
name = "Luca";
}
{
id = 2;
name = "Steve";
name = "Jhon";
}
{
id = 3;
name = "Andrew";
}
Any ideas? would like to use this in the cellForRowAtIndexPath method and I tried to write this: (cm is my class model and myArray is the NSMutableArray which contains an object of cm class)
ClassModel *cm = [myArray objectAtIndex:indexPath.row];
NSMutableArray * resultArray = [NSMutableArray new];
NSArray * groups = [array valueForKeyPath:cm.ID];
for (NSString * groupId in groups)
{
     NSMutableDictionary * entry = [NSMutableDictionary new];
     [insert setObject: groupId forKey: # "groupId"];
     NSArray * groupNames = [array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: # "groupId =% #", groupId]];
     for (int i = 0; i <groupNames.count; i ++)
     {
         NSString * name = [[groupNames objectAtIndex: i] objectForKey: # "name"];
         [entry setObject: name forKey: [NSS string stringWithFormat: # "name% d", i + 1]];
     }
     [resultArray addObject: entry];
}
NSLog (# "% #", resultArray);
But this does not work..maybe because each element in my array is an object?? .. Help!

You have the right basic idea, but you shouldn't try and do this in cellForRowAt. Rather, you need to create a new array that has the data in the required structure and use that array as the source for your tableview. You will also need to create a new class to put in the array; one that has an id and an NSMutableArray for the names (I won't show this but I will call it GroupClassModel)
Use something like:
NSMutableDictionary *groups = [NSMutableDictionary new]
for (ClassModel *cm in array) {
GroupClassModel *gcm = groups[cm.id];
if (gcm == nil) {
gcm = [GroupClassModel new];
gcm.id = cm.id
groups[cm.id] = gcm
}
[gcm.names addObject:cm.name];
}
NSArray *groupedName = [groups allValues];
// Finally, sort groupedName by id if that is required.

Related

How to compare two nsarrays with different values?

Hi i have two nsarrays.
Array A:
arrProductSelection = [[NSArray alloc]initWithObjects:#"English",#"German",#"Russian",#"Chinese",#"Spanish",#"French",#"French",#"French",#"French",#"French",#"French",#"French",#"French",nil];
Array B:
arrProductSelectionB = [[NSArray alloc]initWithObjects:#"deselcted",#"selected",#"selected",#"selected",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",nil];
I need to compare two arrays and get the value from array A by comparing with array B having value as selected. That is i should get german,chinese and russian sepearted by comma as nsstring.
Try this:
NSMutableArray *arrSelected = [[NSMutableArray alloc] init];
NSArray *arrProductSelection = [[NSArray alloc]initWithObjects:#"English",#"German",#"Russian",#"Chinese",#"Spanish",#"French",#"French",#"French",#"French",#"French",#"French",#"French",#"French",nil];
NSArray *arrProductSelectionB = [[NSArray alloc]initWithObjects:#"deselcted",#"selected",#"selected",#"selected",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",#"deselcted",nil];
for(int i = 0; i< arrProductSelectionB.count-1;i ++) {
if ([arrProductSelectionB[i] isEqualToString:#"selected"]) {
[arrSelected addObject:arrProductSelection[i]];
}
}
NSString *strSelected = [arrSelected componentsJoinedByString:#","];
NSLog(#"%#", strSelected);//output: German,Russian,Chinese
If you can make this type of array then manage easly.
(
{
flag = deselcted;
name = English;
},
{
flag = selected;
name = German;
},
{
flag = deselcted;
name = Russian;
},
{
flag = deselcted;
name = Chinese;
}
)
==> Array[(dictionary),(dictionary),.....]
if you need result in an array, Here is the function:
NSMutableArray*resultArray=[[NSMutableArray alloc]init];
for(int i=0; i<arrProductSelectionB.count;i++){
if ([[arrProductSelectionB objectAtIndex:i]isEqualToString:#"selected"]) {
[resultArray addObject:[arrProductSelection objectAtIndex:i]];
}
}
resultArrayhave the values which you need.
first i would make sure both arrays have same counters for safety something like
if (arrProductSelection.count == arrProductSelectionB) {
//than all you need is one for cycle something like :
for (int i = 0; i < arrProductionSelectionB.count; i++) {
if ([arrProductionSelectionB[i] isEqualToString: #"selected"]) {
do something magically with arrProductSelection[i];
}
}
}

Order NSArray with objects

I have an NSDictionary with the following data:
(lldb) po allFriends
{
71685207018702188 = {
id = 71685207018702188;
name = "mikeziri ";
username = mi;
};
93374822540641772 = {
id = 93374822540641772;
name = "Alan Weclipse";
username = zuka;
};
96553685978449395 = {
id = 96553685978449395;
name = "Monica Weclipse";
username = amonica;
};
96556113096345076 = {
id = 96556113096345076;
name = Xavier;
username = branko;
};
97017008427632119 = {
id = 97017008427632119;
name = "Dario Weclipse";
username = tarzan;
};
}
I'm sorting these objects based on the name, if they don't have a name, i will use the username. To do that, i create a new NSDictionary with the name and id and at the end of the method i sort them by name. The code to sort them is the following:
- (NSArray*)orderFriends
{
NSMutableDictionary* newFriendsDict = [[NSMutableDictionary alloc] init];
for (int i=0; i<[allFriends count];i++)
{
NSMutableDictionary* friendsDict = [[NSMutableDictionary alloc] init];
NSDictionary* friend = [allFriends objectForKey:[NSString stringWithFormat:#"%#", [sortedKeysFriends objectAtIndex:i]]];
if ([[friend objectForKey:#"name"] length] != 0)
{
[friendsDict setObject:[friend objectForKey:#"id"] forKey:#"id"];
[friendsDict setObject:[NSString stringWithFormat:#"%#", [friend objectForKey:#"name"]] forKey:#"name"];
}
else
{
[friendsDict setObject:[friend objectForKey:#"id"] forKey:#"id"];
[friendsDict setObject:[NSString stringWithFormat:#"%#", [friend objectForKey:#"username"]] forKey:#"name"];
}
[newFriendsDict setObject:friendsDict forKey:[NSNumber numberWithInt:i]];
}
NSArray* sp = nil;
sp = [[newFriendsDict allValues] sortedArrayUsingComparator:^(id obj1, id obj2){
NSString *one = [NSString stringWithFormat:#"%#", [obj1 objectForKey:#"name"]];
NSString *two = [NSString stringWithFormat:#"%#", [obj2 objectForKey:#"name"]];
return [one compare:two];
}];
return sp;
}
The problem is that the end result is wrong:
(lldb) po sp
<__NSArrayI 0x160491a0>(
{
id = 93374822540641772;
name = "Alan Weclipse";
},
{
id = 97017008427632119;
name = "Dario Weclipse";
},
{
id = 96553685978449395;
name = "Monica Weclipse";
},
{
id = 96556113096345076;
name = Xavier;
},
{
id = 71685207018702188;
name = "mikeziri ";
},
)
Case sensitive. make all string small or big.
You could also just change
return [one compare:two];
to
return [one compare:two options: options:NSCaseInsensitiveSearch];
Than it will be ordered alphabetically, no matter if upper or lower case...
Several things: There is no reason to build different dictionaries in order to sort, and good reason NOT to do so.
You already found the method sortedArrayUsingComparator. That takes a block that is used to compare pairs of objects, and returns a sorted array. You can use that method to implement any sorting criteria you want.
I would suggest writing a comparator block that compares the name properties of your objects unless it's blank, and uses username if that's blank. It would only be a few lines of code:
NSArray *sortedFriends = [[allFriends allValues] sortedArrayUsingComparator:
^(NSDictionary *obj1, NSDictionary *obj2)
{
NSString* key1 = obj1[#"name"] ? obj1[#"name"] : obj1[#"username"];
NSString* key2 = obj2[#"name"] ? obj2[#"name"] : obj2[#"username"];
return [key1 caseInsensitiveCompare: key2];
}];
EDIT: I just noticed (from your edit of my post) that you are starting from a dictionary, not an array. So what you want to do is to create a sorted array of all the values in the dictionary? Is it acceptable to discard the keys for all the items in your dictionary, and end up with a sorted array of the values?
The other thing you could do would be to build an array of the dictionary keys, sorted based on your sort criteria. Then you could use the array of keys to fetch the items from your dictionary in sorted order.

How to get JSON response array all index values?

I need to get JSON response array all indexes values and maintain separate array. Here below I have posted my JSON response and I wanted to get console output looks like below also. Please help me.
response : [ {
A = [ {
name : "sons";
age = [
4
];
},
{
name : "rondo";
age = [
2
];
},
];
} ]
I need to store separate array separate values looks like below console output
2014-09-18 10:24:39.461 Myapp[1133:60b] RESULT : {
name = "sons";
age = 4;
}
2014-09-18 10:24:39.462 Myapp[1133:60b] RESULT : {
name = "rondo";
age = 2;
}
Here below I tried but I Know I can get only 0th index value but I need to get all index value from JSON response array:
myvalue = [NSString stringWithFormat:#"%#",[[[[responsData objectAtIndex:0] valueForKey:#"A"] objectAtIndex:0] valueForKey:#"name"]];
if you want to get all objects, get the array using the respective key.Then store the result in another array by iterating the for loop according to array count.
NSArray *recordsArr = [[responsedata objectAtIndex:0] valueForKey:#"A"];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [recordsArr count]; i ++) {
NSMutableDictionary *recordDict = [[NSMutableDictionary alloc] init];
[recordDict setObject:[[recordsArr objectAtIndex:i] valueForKey:#"name"] forKey:#"name"];
[recordDict setObject:[[[recordsArr objectAtIndex:i] valueForKey:#"age"] objectAtIndex:0] forKey:#"age"];
[resultArray addObject:recordDict];
}
NSLog(#"%#",resultArray);
output:
2014-09-18 12:49:22.047 testprj[1044:60b] (
{
age = 4;
name = sons;
},
{
age = 2;
name = rondo;
}
)
NSString *strName = (NSString *) [yourArray valueForKey:#"name"];
NSInteger age = [(NSNumber *) [yourArray valueForKey:#"age"] integerValue];

ios sort a mutable dictionary order [duplicate]

This question already has answers here:
NSDictionary with ordered keys
(9 answers)
Closed 8 years ago.
I saw many examples on SO but I'm not sure if it applies to this situation. Everywhere it says NSMutableDictionries are not guaranteed an order...but I'm getting my data from the server...so my NSMuteDic looks like this:
{
joe = (
{
fromName = joe;
id = 25;
theMessage = "this is going to be a really big message...";
timeAdded = "2014-04-07 21:08:12";
toName = "me";
},
{
fromName = joe;
id = 10;
theMessage = "why???";
timeAdded = "2014-04-05 20:10:04";
toName = "me";
}
);
bob = (
{
fromName = "me";
id = 24;
theMessage = "blah blah";
timeAdded = "2014-04-06 21:15:06";
toName = bob;
},
{
fromName = bob;
id = 22;
theMessage = message;
timeAdded = "2014-04-06 20:11:57";
toName = "me";
}
);
//more entries here
}
What I want to do is change the order...put bob first and joe second. Is this really impossible to do? I saw many very complex solutions...there's no easy way to do this with just a for loop?
cellForRowAtIndexPath:
NSMutableArray *temp = [myDict objectForKey:keys[indexPath.row]];
cell.Message.text = [[reverse lastObject] valueForKey:#"theMessage"];
cell.dateTime.text = [[reverse lastObject] valueForKey:#"timeAdded"];
return cell;
This is how I'm using it...and when a row is selected I pass the array to the next view controller. The reason why I want to reorder is if a new message will be inserted in the pushed view controller, I want that dictionary to be first in the list so the root view controller can be reordered.
NSArray *keys = [myDict allKeys];
[myDict removeObjectForKey:to];
NSMutableDictionary *temp = [NSMutableDictionary dictionaryWithCapacity:[myDict.count];
temp = myDict;
[myDict removeAllObjects];
[myDict setObject:currentDict forKey:to];
for (int i=0; i<temp.count; i++) {
[myDict setObject:[temp valueForKey:keys[i]] forKey:keys[i]];
}
That's not working because it looks like since myDict is a NSObject, temp gets changed every time myDict changes...from the looks of it the logic should work but it isn't...
NSMutableDictionary is not ordered. There is nothing you can do to guarantee the order of keys because NSDictionary makes no attempt to preserve any particular ordering. To go over a dictionary in a particular order, you have to make an array of the keys that is in the order you want, then iterate that and fetch the corresponding values.
// Get the keys
NSArray *keys = [myDict allKeys];
// Sort the keys
NSArray *sortedArray = [NSArray arrayWithArray:[keys sortedArrayUsingComparator:^(NSString* a, NSString* b) {
return [a compare:b];
}]];
// Iterate the dictionary
for (NSUInteger n = 0 ; < [sortedArray count]; n++) {
id value = [myDict objectForKey:[sortedArray objectAtIndex:n]];
}

NSDictionary: Find a specific object and remove it

I have NSMutableDictionary that looks like this:
category = (
{
description = (
{
id = 1;
name = Apple;
},
{
id = 5;
name = Pear;
},
{
id = 12;
name = Orange;
}
);
id = 2;
name = Fruits;
},
{
description = (
{
id = 4;
name = Milk;
},
{
id = 7;
name = Tea;
}
);
id = 5;
name = Drinks;
}
);
Now, when a user performs an action in my application, I get the #"name"-value of the object, like "Apple". I would like to remove that object from the dictionary, but how will can I reach this object with the
[myDictionary removeObjectForKey:]
method?
At a high level you need to get a reference to the "description" array. Then iterate through the array getting each dictionary. Check the dictionary to see if it has the matching "name" value. If so, remove that dictionary from the "description" array.
NSString *name = ... // the name to find and remove
NSMutableArray *description = ... // the description array to search
for (NSUInteger i = 0; i < description.count; i++) {
NSDictionary *data = description[i];
if ([data[#"name"] isEqualToString:name]) {
[description removeObjectAtIndex:i];
break;
}
}
To remove something from an INNER array:
NSString* someFood = <search argument>;
NSArray* categories = [myDictionary objectForKey:#"category"];
for (NSDictionary* category in categories) {
NSArray* descriptions = [category objectForKey:#"description"];
for (int i = descriptions.count-1; i >= 0; i--) {
NSDictionary* description = [descriptions objectForIndex:i];
if ([[description objectForKey:#"name"] isEqualToString:someFood]) {
[descriptions removeObjectAtIndex:i];
}
}
}
To remove an entire group (eg, "Fruits") from the outer array is simpler.

Resources