Use nsdictionary to compile the table - ios

i've an array with a variable number of nsdictionary.
NSDictionary * name1 = #{#"name" : #"anthony",
#"born" : #(1989),
#"lives" : #(5)};
NSDictionary *name2 = #{#"name" : #"pietro",
#"born" : #(1982),
#"lives" : #(2)};
NSArray *people = #[anthony, pietro];
basically i need to populate the cells of my table with the name inside "name" in nsdictionary.
How can i do that?

Assuming from your code snippet that all your name dictionaries are in the array self.people.
NSString *nameForCell=((NSDictionary *)self.people[indexPath.row])[#"name"];

Related

How can i assign value of nsmutable array which is inside of nsmutable dictionary into another nsmutable dictionary

How can i assign value of nsmutable array which is inside of nsmutable dictionary into another nsmutable dictionary or NSDictionary?
NSMutableDictionary *readers = [[NSMutableDictionary alloc] init];
[readers setObject:[[NSMutableArray alloc] init] forKey:#"id"];
readers[#"publicAccess"] = #NO;
// Create dictionary of parameters to be passed with the request
NSDictionary *data = #{
// #"reader_ids": [NSString stringWithFormat:#"%#",[readers[#"id"]componentsJoinedByString:#","]],
};
NSDictionary *data = #{
#"reader_ids": // i need here values of "id" as string which is separated by comma since **reader_ids** is string property and id is MSMutable Array which contains datas.
I need to get value of both id and publicAccess and assign into another NSDictionary.
Try this
NSMutableArray *mArray = readers[#"id"];
BOOL publicAccess = readers[#"publicAccess"];
NSNumber *num = [NSNumber numberWithBool: publicAccess];
NSString * result = [mArray componentsJoinedByString:#","]
NSDictionary * data = #{#"readers_ids" :result,#"publicAccess" : num};

iOS - Sort NSDictionay keys by sub value

I have a NSDictionary with currency-codes as keys and as values another NSDictionary inside containing a NSString (currency name) + a NSArray (list of coins):
The goal is to get a NSArray with currency-keys (AED, ARS, ...), sorted by name-value inside.
I know how to sort by keys and values, but can't figure out how to sort by the a value inside a NSDictionary inside a NSDictionary.
The following only gives me a sorted NSArray with the values, but I loose the keys:
NSMutableArray *dictValues = [[self.currencyDict allValues] mutableCopy];
[dictValues sortUsingComparator: (NSComparator)^(NSDictionary *a, NSDictionary *b)
{
NSString *key1 = [a objectForKey: #"name"];
NSString *key2 = [b objectForKey: #"name"];
return [key1 compare: key2];
}
];
In order to convert a dictionary of dictionaries into an array of dictionaries without losing the key, the first step is to put the key into the dictionary. In other words, you need to convert this
Root
AED
name "some name"
objects ...
ARS
name "other name"
objects ...
to this
Root
AED
name "some name"
objects ...
key "AED"
ARS
name "other name"
objects ...
key "ARS"
and then call allValues and sort the resulting array.

Grouping NSArray of NSDictionary based on a key in NSDictionay

I am trying to filter out a NSArray of NSDictionaries. With my below example, I want dict1, dict2 & dict4 grouped in one array, dict3 & dict5 grouped in second array and dict6 in third array.
I am getting this data in NSArray, so essentially the "orig" array below is my input and I know that I need to do grouping based on "Name" key.
Instead of looping through the NSArray I though of using valueForKeyPath to return me array based on the key path but this does not work (crashes with logs -[NSMutableArray addObjectsFromArray:]: array argument is not an NSArray').
Any suggestion.
NSDictionary *dict1 = #{#"Name" : #"T1", #"Age" : #"25"};
NSDictionary *dict2 = #{#"Name" : #"T1", #"Age" : #"25"};
NSDictionary *dict3 = #{#"Name" : #"T2", #"Age" : #"27"};
NSDictionary *dict4 = #{#"Name" : #"T1", #"Age" : #"25"};
NSDictionary *dict5 = #{#"Name" : #"T2", #"Age" : #"27"};
NSDictionary *dict6 = #{#"Name" : #"T3", #"Age" : #"28"};
NSArray *orig = #[dict1, dict2, dict3, dict4, dict5, dict6];
NSMutableArray *final = [NSMutableArray array];
final = [orig valueForKeyPath:#"#unionOfArrays.Name"];
NSLog(#"Final = %#", final);
It's a little hard to tell if what you want is three different arrays where each one only contains entries with a specific Name value (as your first paragraph suggests) or if you want a single array where the entries are sorted by Name (as your second paragraph suggests). Regardless,
To sort orig by the value of the Name field:
NSArray *sortedByName = [orig sortedArrayUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"Name" ascending:YES]]];
To get a new array by selecting only entries with a specific value for Name:
NSArray *t1Only = [orig filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"Name = %#", #"T1"]];
If the desired output is an array of arrays, you can get there by building a dictionary keyed by the name attribute in the orig dictionaries:
- (NSArray *)collateByName:(NSArray *)original {
NSMutableDictionary *collate = [NSMutableDictionary dictionary];
for (NSDictionary *d in original) {
NSString *newKey = d[#"Name"];
NSMutableArray *newValue = collate[newKey];
if (!newValue) {
newValue = [NSMutableArray array];
collate[newKey] = newValue;
}
[newValue addObject:d];
}
return [collate allValues];
}
It's a little verbose, but clear, I think. If you want to decide the attribute to distinguish with programmatically, pass in another param called attribute and replace the literal #"Name" with it.

Getting an NSDictionary by filtering another NSDictionary

Hope someone could help me with that :
I'm using a NSDictionary to fill a UITableView.
Its model is like [key:userID => value:userName].
The tableView is only filled with userName but when clicked, it has to send the userID related.
The problem comes when I want to filter the UITable. I only found the way to filter a Dictionary by transforming it into NSArray (using Predicate) but it make me loose the relation between userNames and userIDs.
A solution would be to filter the initial NSDictionary to get a filtered NSDictionary (with still the relational key/value), but I don't know how to do that. I only found solutions to get Arrays.
How could I do that, or is there a better solution to do it?
There is a much better solution, François.
Create, from your NSDictionary (I will call it here myDictionary), an NSArray like this (declare it in your interface file):
NSArray *arrayForTableView;
Then, just after you load your NSDictionary, do the following:
arrayForTableView = [myDictionary allKeys]; // so you will have an array of all UserID's
Now, in your tableView: cellForRowAtIndexPath: method, you can do it like this:
cell.textLabel.text = [myDictionary objectForKey:[arraForTableView objectAtIndex:indexPath.row]];
And then, when you will want to pass the userID when the user selects the cell, in your tableView: didSelectRowAtIndexPath: you just do it this way:
id userIDSelected = [arraForTableView objectAtIndex:indexPath.row];
Then, when you want to filter the array according to the search, you can simply recreate your arrayForTableView, by "scanning" your NSDictionary this way:
NSString *typedString;
NSMutableArray *arrayFiltered = [NSMutableArray array];
for (int i = 0; i < [[myDictionary allKeys] count]; i++)
{
if ([[myDictionary objectForKey:[[myDictionary allKeys] objectAtIndex:i]] rangeOfString:typedString].location != NSNotFound)
{
[arrayFiltered addObject:[[myDictionary allKeys] objectAtIndex:i]];
}
}
arrayForTableView = arrayFiltered;
This way, you won't even need to change your UITableView dataSource and delegate methods.
You can do following to get value(userID) for selected key(userName) :
//iterate through whole dictionary
for(id key in yourNSDictionary)
{
// if key is the userName clicked
if([key isEqualToString:selectedUserName])
{
//userID for clicked userName
int userID = [yourNSDictionary objectForKey:#selectedUserName];
}
}
you're using an NSDictionary to populate an UITableView and this UITableView is only filled with the username which you get by doing
[dictionary objectForKey#"userID"];
a NSDictionary has two functions allkeys and allValues
NSArray* allUserID = [dictionary allKeys];
NSArray* allUserNames = [dictionary allValues];
this is a parallel arrays so that the index of one array, runs parallel with it's associated array.
Each cell of the table cell could also be a custom class that holds a reference to it's own id and username, this will allow you to only pass the cell and have it's data.
you can read about those functions in the NSDictionary documentation
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html
i would recommend creating an NSArray or NSMutableArray with NSDictionary values - UITableViews are meant to be driven by arrays, where the array index matches the row number. Then you can easily create a custom filter for the array of dictionaries which take into account your data structure. Your code might include parts of this sample code:
NSString *idKey = #"userId";
NSString *nameKey = #"userName";
NSArray *arr = #[
#{
idKey : #(24),
nameKey : #"Oil Can Henry"
},
#{
idKey : #(32),
nameKey : #"Doctor Eggman"
},
#{
idKey : #(523),
nameKey : #"Sparticus"
},
];
NSString *searchTerm = #"Spar";
NSArray *newArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject[nameKey] hasPrefix:searchTerm];
}]];
Advantages:
a single data structure to represent all your data
inherent, deterministic ordering
support for NSPredicate filtering

NSDictionary filled with JSON data

I call an URL that returns me JSON (I use JSONKit). I convert it to a NSString that is this way:
[{"name":"aaaaaa","id":41},{"name":"as","id":23},...
And so on. I want to fill an UIPickerView with only the "name" part of the JSON. But, when the user selects a name, i need the "id" parameter, so i've thought to fill a NSDictionary with the JSON (setValue:id for key:name), so i can get the value picked by the user, and get the id from the dictionary. how could I fill an array with only the "name" of the JSON?
Im a bit lost with the JSONKit library, any guidance? Thank you.
First of all I don't think that its a good idea to have name as key in a dictionary, since you can have many identical names. I would go for id as key.
Now, what you could do is:
NSString *myJson; //Suppose that this is the json you have fetched from the url
id jsonObject = [myJson objectFromJSONString];
// Now you have an array of dictionaries
// each one having 2 key/value pairs (name/id)
NSArray *names = [jsonObject valueForKeyPath:#"name"];
NSArray *ids = [jsonObject valueForKeyPath:#"id"];
// Now you have two parallel arrays with names / ids
Or you could just iterate your json object and handle the data yourself:
for (id obj in jsonObject)
{
NSString *name = [obj valueForKey:#"name"];
NSNumber *id = [obj valueForKey:#"id"];
// Do whatever you like with these
}

Resources