Order NSArray with objects - ios

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.

Related

Group element in NSMutableArray which contains object

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.

How to retrieve NSStrings stored in multiple NSArrays inside of an NSArray

I'm building an "invite friends" feature.
It's already working I just have one issue I'm wrestling with.
I'm retrieving my contact list, and every time I select a contact I'm adding them to a NSMutableArray which I'm calling "selectedUser".
So each item in the NSMutableArray at this point are "Dictionaries" and some of the values are "Dictionaries" as well. Especially the "phones" key I'm trying to access and retrieve the value key.
What I'm trying to accomplish is to only retrieve the "phone numbers" in strings stored them inside a NSArray that I can then past to [messageController setRecipients:recipents]; recipents being the array of only NSStrings of phone numbers.
This is my code so far, and what I'm getting is a NSArray with multiple NSArrays in it were each array only has one string being the phone number.
NSArray *titles = [self.selectedUsers valueForKey:#"phones"];
NSArray *value = [titles valueForKey:#"value"];
NSLog(#"Output the value: %#", value);
NSArray *recipents = value;
This is what I get in the log
2016-01-04 12:27:59.721 InviteFriends[4038:1249174] (
(
"(305) 731-7353"
),
(
"(786) 306-2831"
),
(
"(305) 333-3297"
)
)
This is the log of the dictionary itself
{
birthday = "";
company = "";
createdAt = "2015-09-06 16:14:18 +0000";
department = "";
emails = (
);
firstName = "Lola";
firstNamePhonetic = "";
id = 699;
jobTitle = "";
lastName = "";
lastNamePhonetic = "";
middleName = "";
nickName = "";
note = "";
phones = (
{
label = Home;
value = "(305) 503-3957";
}
);
prefix = "";
suffix = "";
updatedAt = "2015-09-23 23:31:25 +0000";
}
)
Thanks
If I am understanding this correctly, on the line where you write
NSArray *value = [titles valueForKey:#"value"];,
You are trying to index the NSArray full of dictionaries using the index "value", which doesn't make sense. You should instead loop through your titles array, pull out the value from each dictionary element, and then append that element to your recipents array.
Here is some sample code that should do what I think you want.
NSArray *titles = [self.selectedUsers valueForKey:#"phones"];
NSMutableArray *recipients = [[NSMutableArray alloc] init];
for (NSDictionary* dict in titles) {
NSString* value = [dict objectForKey:#"value"];
[recipients addObject:value];
}
NSLog(#"Phone Numbers: %#",recipients);
Here is the solution I came up with.
First run a for loop to grab the first key. Then nest another for loop to grab the second key.
NSArray *values = self.selectedUsers;
NSMutableArray *recipients = [[NSMutableArray alloc] init];
NSArray *values = self.selectedUsers;
NSMutableArray *recipients = [[NSMutableArray alloc] init];
for (NSDictionary* dict in values) {
// Grabs phones key
NSDictionary *titles = [dict objectForKey:#"phones"];
for (NSDictionary* dict2 in titles) {
// Grabs the "value" key
NSString* value = [dict2 objectForKey:#"value"];
[recipients addObject:value];
}
}

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];

Get a value from nsdictionary

I want to give a key value from my NSDictionary and get the value associated to it.
I have this:
NSArray *plistContent = [NSArray arrayWithContentsOfURL:file];
NSLog(#"array::%#", plistContent);
dict = [plistContent objectAtIndex:indexPath.row];
cell.textLabel.text = [dict objectForKey:#"code"];
with plistContent :
(
{
code = world;
key = hello;
},
{
code = 456;
key = 123;
},
{
code = 1;
key = yes;
}
)
So how do I get "hello" by giving the dictionary "world"?
If I understand your question correctly, you want to locate the dictionary where "code" = "world" in order to get the value for "key".
If you want to keep the data structure as it is, then you will have to perform a sequential search, and one way to do that is simply:
NSString *keyValue = nil;
NSString *searchCode = #"world";
for (NSDictionary *dict in plistContents) {
if ([[dict objectForKey:#"code"] isEqualToString:searchCode]) {
keyValue = [dict objectForKey:#"key"]); // found it!
break;
}
}
However if you do alot of this searching then you are better off re-organizing the data structure so that it's a dictionary of dictionaries, keyed on the "code" value, converting it like this:
NSMutableDictionary *dictOfDicts = [[NSMutableDictionary alloc] init];
for (NSDictionary *dict in plistContents) {
[dictOfDicts setObject:dict
forKey:[dict objectForKey:#"code"]];
}
(note that code will break if one of the dictionaries doesn't contain the "code" entry).
And then look-up is as simple as:
NSDictionary *dict = [dictOfDicts objectForKey:#"world"]);
This will be "dead quick".
- (NSString*) findValueByCode:(NSString*) code inArray:(NSArray*) arr
{
for(NSDictonary* dict in arr)
{
if([[dict valueForKey:#"code"] isEqualToString:code])
{
return [dict valueForKey:#"key"]
}
}
return nil;
}

Getting values from NSDictionary in foreach?

I have a view that has tableviewcells on it, loaded with different "key values" as the label. When I tap on one I open another view. However here, I pass the dictionary for just that key, for example I would pass this:
{
key = Budget;
value = {
"2012 Budget Report" = {
active = 0;
author = "xxxxx xxxxxx";
date = "October 27, 2012";
description = "Example";
dl = "53 downloads";
email = "xxx#xxxxx.com";
ext = DOCX;
fortest = "Tuesday, November 6";
id = 5;
subject = budget;
testdate = "Tuesday, November 6";
title = "Budget spreadSheet";
};
"2005 - 2008 Budget Report" = {
active = 0;
author = "xxxxxxx xxxxx";
date = "November 3, 2012";
description = "Example";
dl = "18 downloads";
email = "xxxxx#xxxxx.com";
ext = DOCX;
title = "Budget report";
};
};
}
How do I get each of these values? Thanks.
Please note: the titles in value array are subject to change... More could be added, one could be deleted, so I need a general solution.
Considering the dictionary you passed is saved in iDictionary.
NSDictionary *iDictionary // Input Dictionary;
NSDictionary *theValues = [NSDictionary dictionaryWithDictionary:[iDictionary valueForKey:#"value"]];
for (NSString *aKey in [theValues allKeys]) {
NSDictionary *aValue = [theValues valueForKey:aKey];
NSLog(#"Key : %#", aKey);
NSLog(#"Value : %#", aValue);
// Extract individual values
NSLog(#"Author : %#", [aValue objectForKey:#"author"]);
// If the titles are dynamic
for (NSString *aSubKey in [aValue allKeys]) {
NSString *aSubValue = [aValue objectForKey:aSubKey];
NSLog(#"SubKey : %#, SubValue = %#", aSubKey, aSubValue);
}
}
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSArray *arrBudget= [jsonDictionary objectForKey:#"Budget"];
So here arrBudget will contain All the values And you can Pass the array to detail view.
Another approach if keys and objects are useful in the "foreach" logic :
NSDictionary *dict = #{
#"key1": #"value1",
#"key2": #"value2",
#"key3": #"value3",
};
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(#"Your key : %#", key);
NSLog(#"Your value : %#", [obj description]);
// do something...
}];

Resources