NSDictionary inside NSMutableArray (iOS) - objective-c

NSArray *arrayBlockData = [data objectForKey:kData];
for (NSDictionary *dictTicket in arrayBlockData) {
NSString *blockId = [dictTicket objectForKey:#"block_id"];
[dictJson setObject:blockId forKey:#"block_id"];
[self.arrblockIds addObject:[dictTicket objectForKey:#"block_id"]];
}
[arrkeysAndValues addObject:dictJson];
NSLog(#"arrkeysAndValues %#",arrkeysAndValues);
reponse is :
arrKeysValues (
{
"block_id" = 624;
},
{
"block_id" = 624;
},
it should be :
arrKeysValues (
{
"block_id" = 623;
},
{
"block_id" = 624;
}

Your question isn't clear. But the code sample on how you put NSDictionary inside NSMutableArray is
NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setValue:#623 forKey:#"block_id"];
NSMutableDictionary *dict2 = [NSMutableDictionary new];
[dict2 setValue:#624 forKey:#"block_id"];
NSMutableArray *newArray = [NSMutableArray new];
[newArray addObject:dict];
[newArray addObject:dict2];
NSLog(#"%#", newArray);

Related

create a dictionary with an array of dictionaries

Noob here. I recently started working with objective C, and currently I am stuck with dictionary concept. I want to create a json object as shown below:
{"UserData": {
"Name": Mike Smith,
"Age": 32,
"category": [1,2,3],
"Weekly Data": [
{"Monday" : [1.0,2.0,3.0]},
{"Tuesday": [1.0,2.0,3.0]}
]
}
}
I wrote the following piece of code which doesn't give the desired result. I wonder if someone could help me.
-(NSString*)populateUserPreferences
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *categorydata = [[NSMutableArray alloc] init];
NSMutableArray *weeklydata = [[NSMutableArray alloc] init];
for (int i=0;i<4; i++)
{
[categorydata addObject:[NSNumber numberWithInt:i]];
}
NSMutableArray *mondaydata = [[NSMutableArray alloc] init];
for (int j=0; j<3; j++)
{
[mondaydata addObject:[NSNumber numberWithInt:j]];
}
NSMutableArray *tuesdaydata = [[NSMutableArray alloc] init];
for (int j=0; j<3; j++)
{
[tuesdaydata addObject:[NSNumber numberWithInt:j]];
}
NSDictionary *monday = [NSDictionary dictionaryWithObject:mondaydata];
NSDictionary *tuesday = [NSDictionary dictionaryWithObject:tuesdaydata];
[weeklydata addObject: monday ];
[weeklydata addObject: tuesday ];
}
[dict setObject:[NSString stringWithFormat:"Mike Smith"] forKey:#"Name"];
[dict setObject:[NSNumber numberWithInteger:32.0] forKey:#"Age"];
[dict setObject:categorydata forKey:#"category"];
[dict setObject:weeklydata forKey:#"Weekly Data"];
NSString * userdata = [dict JSONRepresentation];
NSLog(request);
NSDictionary *userdataJson = [NSDictionary dictionaryWithObject:dict forKey:#"userData"];
return [userdataJson JSONRepresentation];
}
Thanks in advance for looking into it.
Apoorva
The mistake is when creating the monday and tuesday dictionary.
// mondaydata & tuesday is just array.
NSDictionary *monday = [NSDictionary dictionaryWithObject:mondaydata];
NSDictionary *tuesday = [NSDictionary dictionaryWithObject:tuesdaydata];
This code is mistake since you did not assign the dictionary properly (where is the key for the dictionary?). Instead you should do:
NSDictionary *mondayDict = [[NSDictionary alloc] init];
[mondayDict setObject:mondaydata forKey:"Monday"];
NSDictionary *tuesdayDict = [[NSDictionary alloc] init];
[tuesdayDict setObject:tuesdaydata forKey:"Tuesday"];
Then you can add mondayDict and tuesdayDict to your array weeklydata.
ps. just a note, name your variable meaningfully. For example, mondaydata is not descriptive enough. You should use mondayArr for example. To easily identify it is an array. Just a normal coding practice to share.
NSDictionary * dict = #{#"UserData": #{
#"Name": #"Mike Smith",
#"Age": #32,
#"category": #[#1,#2,#3],
#"Weekly Data": #[
#{#"Monday" : #[#1.0,#2.0,#3.0]},
#{#"Tuesday": #[#1.0,#2.0,#3.0]}
]
}
};
NSError * error = nil;
NSData * data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
// Do what you want
}

Objective C NSDictionary JSON in One line

i'm working on one objective C application where i'm taking JSON data and i need to insert this data(date) inside Dictionary fillDefaultColors. My fillDefaultColors should be in format like this:
self.fillDefaultColors = #{ #"2017/06/18":greenColor,
#"2017/06/19":orangeColor,
#"2017/06/20":greenColor,
...
};
but when i print in console log they are each in separate row and in application i can see colour just for last item from JSON
2017-06-19 15:30:12.310 CalendarTest[1905:364525] {
"2017/06/20" = "greenColor";
}
2017-06-19 15:30:12.311 CalendarTest[1905:364525] {
"2017/06/18" = "orangeColor";
}
So in application i see background for last date in console 2017/06/18
Here is my code
NSError *error = nil;
NSURL *url = [NSURL URLWithString: #"http://..."];
NSData *data = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&error];
if(!error)
{
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
NSMutableArray *array= [json objectForKey:#"horses"];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
self.fillDefaultColors = #{date: tempColor};
NSLog(#"%#", _fillDefaultColors);
}
}
JSON: {"horses":[{"id":1,"name":"Horse","date":"2017/06/17","averagetemperature":28},{"id":1,"name":"Horse","date":"2017/06/18","averagetemperature":25}]}
Thanks
it s because you are allocating a new dictionary in each iteration:
self.fillDefaultColors = #{date: tempColor};
you need to append instead:
NSMutableArray *array= [json objectForKey:#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc]init];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
[self.fillDefaultColors setObject:tempColor forKey:date];
NSLog(#"%#", _fillDefaultColors);
}
This is the same solution as in Hussein's answer but with Modern Objective-C Syntax – which has been introduced at least 5 years ago.
NSArray *horses = json[#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc] init];
for (NSDictionary *horsedata in horses)
{
NSString *date = horsedata[#"date"];
NSNumber *averagetemp = horsedata[#"averagetemperature"];
self.fillDefaultColors[date] = (averagetemp.integerValue == 28) ? greenColor : orangeColor;
NSLog(#"%#", _fillDefaultColors);
}

Reading from SQL database into NSArray

I have an iPad that reads data from an SQL database. The following code works fine and retrieves 2 fields from each record and reads them into an NSArray.
I now need to read 5 of the fields and I can't help but think that there is a better way of doing it rather than running 5 separate queries through php (the getinfo.php file with the choice parameter set to pick the different fields).
Any pointers to a better method for doing this?
NSString *strURLClass = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=1&schoolname=",obsSchoolName];
NSArray *observationsArrayClass = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsClass = [observationsArrayClass objectEnumerator];
NSString *strURLDate = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=5&schoolname=",obsSchoolName];
NSArray *observationsArrayDate = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLDate]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsDate = [observationsArrayDate objectEnumerator];
id className, dateOfObs;
while (className = [enumForObsClass nextObject])
{
dateOfObs = [enumForObsDate nextObject];
[observationListFromSQL addObject:[NSDictionary dictionaryWithObjectsAndKeys:className, #"obsClass", dateOfObs, #"obsDate",nil]];
}
Yes, you can do that with less code by "folding" the statements into a loop, and using a mutable dictionary:
// Add other items that you wish to retrieve to the two arrays below:
NSArray *keys = #[#"obsClass", #"obsDate"]; // Key in the dictionary
NSArray *choices = #[#1, #5]; // Choice in the URL string
NSMutableArray *res = [NSMutableArray array];
NSMutableArray *observationListFromSQL = [NSMutableArray array];
for (int i = 0 ; i != keys.count ; i++) {
NSNumber *choice = choices[i];
NSString *strURLClass = [NSString stringWithFormat:#"http://wwwaddress/getinfo.php?choice=%#&schoolname=%#", choice, obsSchoolName];
NSArray *observationsArray = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
NSEnumerator *objEnum = [observationsArrayClass objectEnumerator];
NSString *key = keys[i];
NSMutableDictionary *dict;
if (res.count < i) {
dict = res[i];
} else {
dict = [NSMutableDictionary dictionary];
[res addObject:dict];
}
id item;
while (item = [objEnum nextObject]) {
[res setObject:item forKey:key];
}
}

Create array of dictionary with different keys?

I have following array,I have one array with multiple dictionaries,I need to get that dictionaries for same prod_type and create another array with unique key
nsarray
{
{
prod_type=abc;
fund=100;
};
{
prod_type=abc;
fund=100;
};
{
prod_type=abc;
fund=100;
};
{
prod_type=pqr;
fund=100;
};
{
prod_type=pqr;
fund=100;
};
{
prod_type=xyz;
fund=100;
};
{
prod_type=xyz;
fund=100;
};
I need following array format from above array
nsarray=
{
abc=
{
{
prod_type=abc;
fund=100;
};
{
prod_type=abc;
fund=100;
};
{
prod_type=abc;
fund=100;
};
}
pqr=
{
{
prod_type=pqr;
fund=100;
};
{
prod_type=pqr;
fund=100;
};
}
xyz=
{
{
prod_type=xyz;
fund=100;
};
{
prod_type=xyz;
fund=100;
};
}
}
Use NSPredicate to get desirable result.
NSString *selectedCategory=#"abc";
//filter array by category using predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"prod_type == %#", selectedCategory];
NSArray *filteredArray = [yourAry filteredArrayUsingPredicate:predicate];
NSDictionary *abcDic = [NSDictionary dictionaryWithObject:filteredArray forKey:#"abc"];
[yourNewAry addObject:abcDic];
You can repeat it for other
Here a nice explanation of it predicates
Use this code if you want a fully automated solution (without having to re-specify each prod_type):
NSMutableArray *keys = [originalArray mutableArrayValueForKey:#"prod_type"];
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:keys];
NSArray *uniqueKeys = orderedSet.array;
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
for(NSString *key in uniqueKeys){
NSPredicate *keyPredicate = [NSPredicate predicateWithFormat:#"prod_type = %#",key];
NSDictionary *keyDictionary = [NSDictionary dictionaryWithObject:[originalArray filteredArrayUsingPredicate:keyPredicate] forKey:key];
[resultArray addObject:keyDictionary];
}
NSLog(#"%#",resultArray);
try like this,
NSMutableDictionary *resultdict = [[NSMutableDictionary alloc]init];
NSMutableArray *keysArray =[array mutableArrayValueForKey:#"prod_type"];//here you'l get all the prod_type values in an array
for(int i=0;i<[keysArray count];i++){
NSPredicate *resultPredicate=[NSPredicate predicateWithFormat:#"prod_type CONTAINS %#",[keysArray objectAtIndex:i]];
NSArray* searchResults=[array filteredArrayUsingPredicate:resultPredicate];
[resultdict setObject:searchResults forKey:[keysArray objectAtIndex:i]];
}
NSLog(#"%#",resultdict);
EX:-
NSMutableArray *array =[[NSMutableArray alloc]init];
NSMutableDictionary *dict = [[NSMutableDictionary alloc]initWithObjects:#[#"abc",#"100"] forKeys:#[#"name",#"value"]];
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc]initWithObjects:#[#"pqr",#"100"] forKeys:#[#"name",#"value"]];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc]initWithObjects:#[#"pqr",#"100"] forKeys:#[#"name",#"value"]];
[array addObject:dict];
[array addObject:dict1];
[array addObject:dict2];
NSLog(#"%#",array);
(
{
name = abc;
value = 100;
},
{
name = pqr;
value = 100;
},
{
name = pqr;
value = 100;
}
)
NSMutableDictionary *resultdict = [[NSMutableDictionary alloc]init];
NSMutableArray *keysArray =[array mutableArrayValueForKey:#"name"];
for(int i=0;i<[keysArray count];i++){
NSPredicate *resultPredicate=[NSPredicate predicateWithFormat:#"name CONTAINS %#",[keysArray objectAtIndex:i]];
NSArray* searchResults=[array filteredArrayUsingPredicate:resultPredicate];
[resultdict setObject:searchResults forKey:[keysArray objectAtIndex:i]];
}
NSLog(#"%#",resultdict);
{
abc = (
{
name = abc;
value = 100;
}
);
pqr = (
{
name = pqr;
value = 100;
},
{
name = pqr;
value = 100;
}
);
}

NSArray and NSDictionary

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?
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]).
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
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];
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];
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
);
}