getting the object value in key in dictionary - ios

I have a dictionary with key-value pair populated from JSON returned data.What I wish to do is use the dictionary to populate UITableView.
I have this structure for table:
[Product Name]
By [Manufacturer Name]
What this means is that key is Product Name and Value is Manufacturer Name. I need to get the name of the key and the name of the value. How can this be done? and is it possible without for-loop?

I'd use the enumerateKeysAndObjectsUsingBlock: method. The following code builds a list of the strings you require.
NSMutableArray *names = [NSMutableArray array];
[dictionary enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *object, BOOL *stop) {
[names addObject[NSString stringWithFormat:#"%# By %#",key, object]];
}];

You can use the keyEnumerator of NSDictionary and for each key look up the value. This could look something like this:
for (NSString *p in dict)
{
NSString *m = [dict objectForKey:p];
// do something with (p,m)
}
You should not be concerned with avoiding for-loops. After all, something like a for loop will always happen somewhere underneath.

If your keys are dynamic from json then you can use
NSArray *keys = [dictionary allkeys];
Then in the table View Cell for row at index path method you can populate the table view with the corresponding keys and their values.

NSArray * keys = [results allKeys];
for (int i = 0;i<[keys count];c++){
NSString* productName = [key objectAtIndex:i];
NSString* manufacturerName = [results objectForKey:productName];
}
Hope this helps...
I have assumed the name as strings, you can change the type according to your situation..

Related

Get all values from NSMutableDictionary

I have a simple UITableView, when users adds new rows, these will be added to the NSMutableDictionary. I can retrieve the values for a specific key.
NSArray *myArr = [myDictionary valueForKey:#"Food"];
This will show me all values for key food, this is an example of my NSLog:
(
burger,
pasta )
If I add more objects to myDictionary but for a different key, for example:
NSArray *drinks = [NSArray arrayWithObjects:#"cola",#"sprite",nil];
[myDictionary setObject:drinks forKey:#"Drink"];
I can't retrieve all values using the following code:
NSArray *allMenu = [myDictionary allValues];
It shows me the following NSLog:
(
(
burger,
past
),
(
cola,
sprite
) )
I don't know where is the problem. Why I can't get all values from NSDictionary to NSArray.
If I use the code:
NSArray *allMenu = [[myDictionary allValues] objectAtIndex:0];
will show me the Food values. If I change objectAtIndex to 1 will show me the Drink value.
I am not entirely sure what you are asking, if you are trying to print all of the values within an NSDictionary do the following:
//Gets an array of all keys within the dictionary
NSArray dictionaryKeys = [myDictionary allKeys];
for (NSString *key in dictionaryKeys)
{
//Prints this key
NSLog(#"Key = %#", key);
//Loops through the values for the aforementioned key
for (NSString *value in [myDictionary valueForKey:key])
{
//Prints individual values out of the NSArray for the key
NSLog(#"Value = %#", value);
}
}
You can do this in one line by flattening the returned 2-dimensional array by using key value coding (KVC). I found this in another answer, see the docs. In your case, it looks as follows:
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionary];
NSArray *food = [NSArray arrayWithObjects:#"burger",#"pasta",nil];
[myDictionary setObject:food forKey:#"Food"];
NSArray *drinks = [NSArray arrayWithObjects:#"cola",#"sprite",nil];
[myDictionary setObject:drinks forKey:#"Drink"];
NSArray *allMenue = [[myDictionary allValues] valueForKeyPath:#"#unionOfArrays.self"];
Try this Solution :
- (NSDictionary *) indexKeyedDictionaryFromArray:(NSArray *)array
{
id objectInstance;
NSUInteger indexKey = 0U;
for (objectInstance in myArr)
[mutableDictionary setObject:objectInstance forKey:[NSNumber numberWithUnsignedInt:indexKey++]];
return (NSDictionary *)[myDictionary autorelease];
}

How to look for a specific value in .plist and then retrieve matches

As the title suggests, my .plist file is in this format - I don't know how to mark it up well for you to read. Stackoverflow doesn't understand the format.
root (array)
Item 0 - Dict
numberOfPerson String
recipeName String
recipeIngredients String
Item 1 -Dict
NumberOfPerson String
...
I have a textfield for user and user will enter a couple of strings.
I want to look for matches with input and recipeIngredients of each item.
And when it is found I want to go to that cell in my tableview which i implemented.
how can I accomplish this.
These are what I have tried so far
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
NSArray *arrayOfPlist = [[NSArray alloc] initWithContentsOfFile:path];
This turned out useless I can not use objectForKey
for (int i=0; i<2; i++) {
recipeIngredientsArray = [[arrayOfPlist objectAtIndex:i] objectForKey:#"recipeIngredients"];
}
This didn't help me either I can not maintain a good isequl method
Thanks for the help.
You have an array of dictionaries that you want to filter. Look at using indexesOfObjectsPassingTest:. Run this on the array and test the passed dictionary to check the value of the recipeIngredients value.
NSIndexSet *indexes = [arrayOfPlist indexesOfObjectsPassingTest:^BOOL (NSDictionary *obj, NSUInteger idx, BOOL *stop) {
return [obj[#"recipeIngredients"] rangeOfString:input options:NSCaseInsensitiveSearch].location != NSNotFound;
}];
Then you can use indexes to see if you have any matches and to display them. Or, you could just use filteredArrayUsingPredicate: to filter the array directly:
NSArray *results = [arrayOfPlist filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"recipeIngredients CONTAINS[cd] %#", input]];
and then show only the filtered results in the table view.

Search element in nsdictionary by value

I have nsdictionary which contains elements with following structure
name --> value
email--> key
I get value(of above structure) from user,
now I want to search element in nsdictionary by value(entered by user) not by key, whether it is present in nsdictionary or not and also want to get index of that element if present.
How to do this?
The best to do so would propably be
- (NSArray *)allKeysForObject:(id)anObject
This method of NSDictionary gives you back all the keys having anObject as their value. If you only have each object once in the whole dictionary it will logically return an array with only one key in it.
NSArray * users = ...; //your array of NSDictionary objects
NSPredicate *filter = [NSPredicate predicateWithFormat:#"email = test#gmail.com"];
NSArray *filteredContacts = [contacts filteredArrayUsingPredicate:filter];
for more than one value of email, then use an OR in the predicate:
filter = [NSPredicate predicateWithFormat:#"contact_type = 42 OR contact_type = 23"];
The dictionary data structure has no 'order', so you'd have to search for your key by iterating the collection and looking for the desired value.
Example:
NSString *targetKey = nil;
NSArray *allKeys = [collection allKeys];
for (int i = 0; i < [allKeys count]; ++i) {
NSString *key = [allKeys objectAtIndex:i];
NSString *obj = [collection objectForKey:key];
if ([obj isEqualToString:searchedString]) { // searchedString is what you're looking for
targetKey = key;
break;
}
}
// check if key was found (not nil) & proceed
// ...
You can search the entered value in NSDictionary , but you can't get an index of value , as NSDictionary has no order of key value pair.
NSArray *array = [yourDictionaryObject allValues];
if ([array containsObject:#"userEnteredValue"]) {
<#statements#>
}
You need to iterate through the Dictionary for the keys has the Value of your need:
Try this:
NSArray *keys= [json allKeys];
for (NSString *keysV in keys){
NSLog(#"Keys are %#", keysV);
if([Your_Dict objectForKey: keysV] isEqual:#"string to Match"){
//Do your stuff here
}
}

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

NSMutableDictionary -- using allKeysforObject not retrieving array values

NSMutableDictionary *expense_ArrContents = [[NSMutableDictionary alloc]init];
for (int i = 1; i<=4; i++) {
NSMutableArray *current_row = [NSMutableArray arrayWithObjects:#"payer_id",#"Expense_Type_id",#"Category_Id",#"SubCategory_Id",nil];
[expense_ArrContents setObject:current_row forKey: [NSNumber numberWithInt:i]];
}
NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"];
NSLog(#"%#",[newArray description]);
i want to get the list of key values containing the particular object which is in the array of values stored in nsmutabledictionary for a particular key.
In the line where you get all the keys ([expense_ArrContents allKeysForObject:#"payer_id"];) you actually get keys for an object that is not in any of the array's items. This #"player_id" is different object than the #"player_id" you added in current_row. In fact, maybe all of your rows have different #"player_id" objects (except if the compiler has made some optimization - maybe it threats that same string literal as one object instead of creating new object for each iteration).
Try creating an NSString object for the #"player_id" which you add to the current_row and then get all the keys for that same object:
NSString* playerId = #"player_id";
for(){
NSMutableArray *current_row = [NSMutableArray arrayWithObjects: playerId,...];
...
}
NSArray *newArray = [expense_ArrContents allKeysForObject:playerId];
Your NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"]; will not return any value because in expense_ArrContents there is no such key(#"payer_id"), instead there are keys like 1,2,3 etc.What is your requirement?Want to see what all keys are there in expense_ArrContents just log
NSArray*keys=[expense_ArrContents allKeys];
Try this :
NSMutableArray *array_key=[[NSMutableArray alloc]init];
for (NSString *key in expense_ArrContents) {
if ([[expense_ArrContents objectForKey:key] containsObject:#"payer_id"]) {
[array_key addObject:key];
}
}

Resources