I have array with nsdictionary objects, for ex.:
({"someKey" = "title";
"name" = "someName";
},
{"someKey" = "title";
"name" = "anotherName";
}
{"someKey" = "newTitle";
"name" = "someName";
}
)
Please, help me to sort it in this format:
({"someKey" = "title";
"names": (
{"name" = "someName"},
{"name" = "anotherName"}
)
},
{"someKey" = "newTitle";
"names": (
{"name" = "someName"}
)
}
)
Thanks..
As far as i understand from your question you want to pick individual objects into one single dictionary object..
NSArray *yourArray=.... /* array which contains this data: ({"someKey" = "title";
"name" = "someName";
},
{"someKey" = "title";
"name" = "anotherName";
}
)*/
NSMutableDictionary *newDictionary=[[NSMutableDictionary alloc]init];
for(int i=0;i<[yourArray count];i++){
[newDictionary setObject:[yourArray objectAtIndex:i] forKey:#"names"];
}
({"someKey" = "title";
"name" = "someName";
},
{"someKey" = "title";
"name" = "anotherName";
}
)
Assuming above is equivalent to
NSArray *array=[NSArray arrayWithObjects:dictionary1,dictionary2,nil];
then to achieve below result
(
{
"someKey" = "title";
"names": (
{"name" = "someName"},
{"name" = "anotherName"}
)
}
)
We have this :
//Get name array
NSMutableArray *names=[NSMutableArray array];
for(int i=0;i<[array count];i++)
{
NSDictionary *dictionary=[array objectAtIndex:i];
[names addObject:[dictionary valueForKey:#"name"];
}
NSDictionary *newDictionary=[NSDictionary dictionaryWithOjbectsAndKeys:#"someKey",#"title",names,#"names",nil];
//Your final result is an array with one object ( A Dictionary )
NSArray *finalArray=[NSArray arrayWithObjects: newDictionary,nil];
You just need to traverse the current structure and build a new dictionary with the title as the unique key:
NSEnumerator* arrayEnumerator = [myArray objectEnumerator];
NSDictionary* = dictFromArray;
NSMutableArray* titleArray = [[NSMutableArray alloc] init];
NSMutableDictionary* titleDict = [[NSMutableDictionary alloc] init];
while(dictFromArray = [arrayEnumerator nextObject])
{
currentTitle = [dictFromArray objectForKey:#"someKey"];
currentName = [dictFromArray objectForKey:#"name"];
if([titles containsObject:currentTitle)
{
NSMutableDictionary namesArray = [titleDict objectForKey:currentTitle];
[namesArray addObject:currentName];
}
else
{
[titles addObject:currentTitle];
[titleDict addObject:[NSMutableArray arrayWithObject:currentName] forKey:currentTitle];
}
}
This should give you a dictionary that looks like:
{
title =
(
someName,
anotherName
);
newTitle =
(
someName
)
}
To get the exact structure you have above, I think this should work:
NSArray* titleKeys = [titleDict allKeys];
NSEnumerator* keyEnumerator = [titleKeys objectEnumerator];
NSMutableArray* finalArray = [[NSMutableArray alloc] init];
NSString* key;
while (key = [keyEnumerator nextObject])
{
[finalArray addObject: [NSDictionary
dictionaryWithObjects:(key, [dictArray objectForKey:key])
forKeys:(#"someKey", #"names")]];
}
Related
I am getting a web service repsonse that is an array of dictionary. Each dictionary has objects whose values itself is another dictionary.I need to implement the search within this response,like if i enter "technology" and go for search, I should get those dictionary from the array that has "technology anywhere within that dictionary", Is there a solution to sort out
{
key1 = {
0 = {
"id" = 608;
"b" = "Apple-Iphone";
};
1 = {
"id" = 609;
"b" = "Iphone";
};
2 = {
"id" = 610;
"b" = "Show Text";
};
};
key2 = "Technology resources";
"key3" = {
0 = {
"id" = 1608;
"b" = "I love reading";
};
1 = {
"id" = 1609;
"b" = "I prefer iphone to others";
};
2 = {
"id" = 1610;
"b" = "Mobile technology is great.I am happy to a be developer";
};
};
"key4" = "Mobile technology is the fun";
}
This is First Method
NSMutableDictionary *dict;
NSArray *allKeys = [dict allKeys];
for (NSString *key in allKeys)
{
NSDictionary *innerDict = [dict objectForKey:key];
NSArray *allInnerKeys = [innerDict allKeys];
for (NSString *innerKey in allInnerKeys)
{
NSDictionary *mostInnerDict = [dict objectForKey:innerKey];
NSString *b = [mostInnerDict objectForKey:b];
NSString *search = #"Technology";
NSString *sub = [b substringFromIndex:NSMaxRange([b rangeOfString:search])];
if(sub)
{
// ADD mostInnerDict Object to your Results Array
}
}
}
Or You can Try The Simpler Method
Get Response in NSDATA
Covert NSDATA To NSString
and search in NSSTRING for Substring
Right now i have a dictionary like this, it's just a example, i got A to Z:
(
{
id = 13;
name = "Roll";
firstLetter = R;
},
{
id = 14;
name = "Scroll";
firstLetter = S;
},
{
id = 16;
name = "Rock";
firstLetter = R;
},
{
id = 17;
name = "Start";
firstLetter = S;
}
)
I want to extract the dict has the same firstLetter and combine these into a NSArray object. The expected results like this:
R array:
(
{
id = 13;
name = "Roll";
firstLetter = R;
},
{
id = 16;
name = "Rock";
firstLetter = R;
}
)
and S array:
(
{
id = 14;
name = "Scroll";
firstLetter = S;
},
{
id = 17;
name = "Start";
firstLetter = S;
}
)
How to do that?
I believe the better method would be the one suggested by Saohooou
But it can be optimised as
NSArray *array = #[#{#"id": #13,#"name":#"Roll",#"firstLetter":#"R"},
#{#"id": #14,#"name":#"Scroll",#"firstLetter":#"S"},
#{#"id": #15,#"name":#"Rock",#"firstLetter":#"R"},
#{#"id": #16,#"name":#"Start",#"firstLetter":#"S"}];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[array enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
NSString *key = dict[#"firstLetter"];
NSMutableArray *tempArray = dictionary[key];
if (!tempArray) {
tempArray = [NSMutableArray array];
}
[tempArray addObject:dict];
dictionary[key] = tempArray;
}];
NSLog(#"%#",dictionary);
NSMutableDictionay *dic = [NSMutableDictionay dictionay];
for ( YourObject *obj in yourDic.allValues )
{
NSMutableArray *dateArray = dic[obj.firstLetter];
if ( !dateArray )
{
dateArray = [NSMutableArray array];
[dic setObject:dateArray forKey:obj.firstLetter];
}
[dateArray addObject:obj];
}
so dic is what you want
I assume you organized the dict as an NSArray.
NSMutableDictionary* result = [NSMutableDictionary dictionary]; // NSDictionary of NSArray
for (id entry in dict) {
NSString* firstLetter = [entry firstLetter];
// Find the group of firstLetter
NSMutableArray* group = result[firstLetter];
if (group == nil) {
// No such group --> create new a new one and add it to the result
group = [NSMutableArray array];
result[firstLetter] = group;
}
// Either group has existed, or has been just created
// Add the entry to it
[group addObject: entry];
}
result holds what you want.
try this
NSString *currentStr;
//this int is to detect currentStr
NSInteger i;
NSMutableArray* R_Array = [[NSMutableArray alloc] init];
NSMutableArray* S_Array = [[NSMutableArray alloc] init];
for (NSDictionary *myDict in MyDictArray){
NSString *tempStr = [myDict objectForKey:#"firstLetter"];
if(currentStr = nil && [currentStr isEqualToString:""]){
currentStr = tempStr;
if([currentStr isEqualToString:"R"] ){
[R_Array addObject:myDict];
i = 0;
}else{
[S_Array addObject:myDict];
i = 1;
}
}else{
if([currentStr isEqualToString:tempStr]){
(i=0)?[R_Array addObject:myDict]:[S_Array addObject:myDict];
}else{
(i=0)?[R_Array addObject:myDict]:[S_Array addObject:myDict];
}
}
}
Base on your dictionaries. There are only two type, so i just created two array and use if-else for solving the problem. if there are multy values, you can try switch-case to do it.
Lets do this
NSMutaleDictionary * speDict = [[NSMutableDictionary alloc] init];
for(i=0;i<26;i++){
switch (i){
case 0:
[speDict setObject:[NSMutableArray alloc] init] forKey:#"A"];
break;
case 1:
[speDict setObject:[NSMutableArray alloc] init] forKey:#"B"];
break;
Case 2:
[speDict setObject:[NSMutableArray alloc] init] forKey:#"C"];
break;
...........
Case 25:
[speDict setObject:[NSMutableArray alloc] init] forKey:#"Z"];
break;
}
}
for (NSDictionary *myDict in MyDictArray){
NSString *tempStr = [myDict objectForKey:#"firstLetter"];
switch (tempStr)
case A:
[self addToMySpeDictArrayWithObject:myDict andStr:temStr];
break;
case B:
[self addToMySpeDictArrayWithObject:myDict andStr:temStr];
break;
Case C:
[self addToMySpeDictArrayWithObject:myDict andStr:temStr];
break;
...........
Case Z:
[self addToMySpeDictArrayWithObject:myDict andStr:temStr];
break;
}
-(void)addToMySpeDictArrayWithObject:(NSDictionary*)_dict andStr:(NString*)_str
{
NSMutableArray *tempArray = [speDict objectForKey:_str];
[tempArray addObject:_dict];
}
then the speDict is like
A:
//all firstletter is A
myDict
myDict
myDict
B:
//all firstletter is B
myDict
myDict
.......
First of all the sample you've provided is an array of dicts (not a dict as the question notes). Now, the easiest way to query this array is by using an NSPredicate. Something like this perhaps:
NSArray *objects = ...; // The array with dicts
NSString *letter = #"S"; // The letter we want to pull out
NSPredicate *p = [NSPredicate predicateWithFormat:#"firstLetter == %#", letter];
NSArray *s = [objects filteredArrayUsingPredicate:p]; // All the 'S' dicts
If for some reason you need to group all of your objects without having to ask for a specific letter each time, you could try something like this:
// Grab all available firstLetters
NSSet *letters = [NSSet setWithArray:[objects valueForKey:#"firstLetter"]];
for (NSString *letter in letters)
{
NSPredicate *p = [NSPredicate predicateWithFormat:#"firstLetter == %#", letter];
NSArray *x = [objects filteredArrayUsingPredicate:p];
// Do something with 'x'
// For example append it on a mutable array, or set it as the object
// for the key 'letter' on a mutable dict
}
And of course you could further optimize this approach by implementing a method for filtering the array based on a letter. I hope that this makes sense.
I am using NSMutableArray. I want to fetch the values by date like we do in SQL group by "log_date".
logMuArray (
{
"log_currenttime" = "4:30pm";
"log_date" = "11.12.2011";
"log_duration" = "1:30";
},
{
"log_currenttime" = "4:33pm";
"log_date" = "11.12.2011";
"log_duration" = "2:21";
},
{
"log_currenttime" = "4:40pm";
"log_date" = "11.12.2011";
"log_duration" = "5:30";
},
{
"log_currenttime" = "7:30pm";
"log_date" = "12.12.2011";
"log_duration" = "1:30";
},
{
"log_currenttime" = "7:33pm";
"log_date" = "12.12.2011";
"log_duration" = "2:21";
},
{
"log_currenttime" = "7:40pm";
"log_date" = "12.12.2011";
"log_duration" = "5:30";
},
{
"log_currenttime" = "07:16pm";
"log_date" = "19.12.2011";
"log_duration" = "0:07";
},
{
"log_currenttime" = "7:31pm";
"log_date" = "19.12.2011";
"log_duration" = "0:04";
},
{
"log_currenttime" = "7:33pm";
"log_date" = "19.12.2011";
"log_duration" = "0:03";
},
{
"log_currenttime" = "7:33pm";
"log_date" = "19.12.2011";
"log_duration" = "0:06";
},
{
"log_currenttime" = "7:35pm";
"log_date" = "19.12.2011";
"log_duration" = "0:05";
}
)
**So, I have just performed....
NSLog(#"logMuArray %#",[logMuArray valueForKey:#"log_date"]);
But I want to fetch the UNIQUE dates only.**
I have thought about NSPredicate or Mutable Set etc...
logMuArray (
"11.12.2011",
"11.12.2011",
"11.12.2011",
"12.12.2011",
"12.12.2011",
"12.12.2011",
"19.12.2011",
"19.12.2011",
"19.12.2011",
"19.12.2011",
"19.12.2011"
)
Thanks in advance.....
EDIT:
I have also heared about "#distinctUnionOfObjects"
......
Shanti's answer is close. You want to use the Key-Value Coding collection operator #distinctUnionOfObjects. Place the operator immediately preceding the key which you want it to affect, as if it is a part of the key path you are accessing:
[logMuArray valueForKeyPath:#"#distinctUnionOfObjects.log_date"]
Notice the use of valueForKeyPath:, not valueForKey: The former is a method in the Key-Value Coding protocol, and allows accessing arbitrary depth of attributes. The key path is an NSString made up of dot-separated keys. The result of each key lookup is used in turn to access the next key (starting with the original receiver); by default, valueForKey: is simply called at each step.
You should use NSSet for UNIQUE items like :
NSSet *filteredData = [NSSet setWithArray:[logMuArray valueForKey:#"log_date"]];
You can use KVC for this.
[logMuArray valueForKey:#"#distinctUnionOfArrays.log_date"]
edit: Editing this wrt Josh's Response
[logMuArray valueForKeyPath:#"#distinctUnionOfArrays.log_date"]
Try this logic might help you
-(NSMutableArray *) makeUnique :(NSMutableArray *) array {
int i;
int count = [array count];
for (i =0; i< count ; i++) {
NSRange range = NSMakeRange (i+1, count);
[array removeObject:[array objectAtIndex:i] inRange:range];
}
return array;
}
You can incorporate a set
Here is some example code
NSMutableArray * mArray = [NSMutableArray array];
NSDictionary *d1 = [NSDictionary dictionaryWithObjectsAndKeys:#"foo",#"bar",#"bar",#"oooo",nil];
NSDictionary *d2 = [NSDictionary dictionaryWithObjectsAndKeys:#"boo",#"bar",#"bar",#"oooo",nil];
NSDictionary *d3 = [NSDictionary dictionaryWithObjectsAndKeys:#"boo",#"bar",#"bar",#"oooo",nil];
[mArray addObject:d1];
[mArray addObject:d2];
[mArray addObject:d3];
NSLog(#"the array\n%#", mArray);
NSLog(#"just bar %#", [mArray valueForKey:#"bar"]);
//get unique values
NSSet * set = [NSSet setWithArray:[mArray valueForKey:#"bar"]];
NSLog(#"unique just bar %#", [set allObjects]);
and here is the output
2011-12-20 01:50:59.034 TestEnvironment[32401:207] the array
(
{
bar = foo;
oooo = bar;
},
{
bar = boo;
oooo = bar;
},
{
bar = boo;
oooo = bar;
}
)
2011-12-20 01:50:59.036 TestEnvironment[32401:207] just bar (
foo,
boo,
boo
)
2011-12-20 01:50:59.038 TestEnvironment[32401:207] unique just bar (
foo,
boo
)
I have one more big problem while parse the values from Webservice response. I dont know the key for the values in the webservice response. For example,
class = (
{
"ObjectiveC" =
(
{
"brief_desc" = "ObjectiveC";
date = "2008-02-27";
"event_status" = Attended;
},
{
"brief_desc" = "ObjectiveC";
date = "2008-03-05";
"event_status" = Attended;
},
{
"brief_desc" = "ObjectiveC";
date = "2008-03-12";
"event_status" = Missed;
},
);
},
{
"Java" = (
{
"brief_desc" = "Java";
date = "2008-02-27";
"event_status" = Attended;
},
{
"brief_desc" = "Java";
date = "2008-03-05";
"event_status" = Attended;
},
{
"brief_desc" = "Java";
date = "2008-03-12";
"event_status" = Missed;
},
);
}
);
In this response even we dont know the keys "ObjectiveC" and "Java". The keys("ObjectiveC and Java") should be change in every response retured. How to get values of key (Unknown key)? How can i parse this response and get the values?
I would enumerate through the keys to get the value. Here is an example of enumeration in objective-c.
NSEnumerator *enumerator = [myDictionary keyEnumerator];
id key;
while ((key = [enumerator nextObject])) {
//assuming value will be string
NSString *valueForKey = [myDictionary valueForKey:key];
//assuming value is another dictionary
NSDictionary *subDictionary = [myDictionary objectForKey:key];
}
And if you don't know the keys of the sub dictionaries, you can enumerate through those as well.
NSDictionary has - (NSArray *)allKeys and - (NSArray *)allValues. One of those might help
NSDictionary * lessonDict = [[NSDictionary alloc] initWithObjectsAndKeys:#"Key", #"Value", #"Key 2", #"Value 2", nil];
NSArray *values = [lessonDict allValues];
NSArray *keys = [lessonDict allKeys];
NSLog(#"Keys: %#",keys);
NSLog(#"Values: %#",values);
I have the following JSON value:
-(
{ Key = IsEmail;
Value = 1; },
{ Key = TrackingInterval;
Value = 20; },
{ Key = IsBackup;
Value = 1; },
{ Key = WipeOnRestore;
Value = 1; }
)
How might I go about parsing this object into an array or string? - i.e. eack key values to be stored in an array and each Value to be stored in another array.
Please help me out with this.
Thanks :)
This approach uses the json-framework.
I've shortened your example:
NSString *jsonString = #"[{\"Key\":\"IsEmail\",\"Value\":\"1\"},{\"Key\":\"TrackingInterval\",\"Value\":\"20\"},{\"Key\":\"IsBackup\",\"Value\":\"1\"}]";
NSMutableArray *keys = [NSMutableArray array];
NSMutableArray *values = [NSMutableArray array];
NSArray *json = [jsonString JSONValue];
for (NSDictionary *pair in json) {
[keys addObject:[pair objectForKey:#"Key"]];
[values addObject:[pair objectForKey:#"Value"]];
}
NSLog(#"%#", keys);
NSLog(#"%#", values);
Output:
2011-05-18 14:23:55.698 [36736:207] (
IsEmail,
TrackingInterval,
IsBackup
)
2011-05-18 14:23:55.700 [36736:207] (
1,
20,
1
)
Refere
http://www.xprogress.com/post-44-how-to-parse-json-files-on-iphone-in-objective-c-into-nsarray-and-nsdictionary/
http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/
http://mobile.tutsplus.com/tutorials/iphone/iphone-json-twitter-api/
http://blog.zachwaugh.com/post/309924609/how-to-use-json-in-cocoaobjective-c
Your data is not vald json, You may want to structure it more like this:
var theObj = { IsEmail: 1, TrackingInterval: 20, IsBackup: 1, WipeOnRestore: 1 };
Then you could populate your key and value arrays something like this:
var keys = new Array();
var values = new Array();
for (prop in theObj) {
keys.push(prop);
values.push(theObj[prop]);
}
if the JSON is in below format,
responseString=[ {
Key = IsEmail;
Value = 1;
},
{
Key = TrackingInterval;
Value = 20;
},
{
Key = IsBackup;
Value = 1;
},
{
Key = WipeOnRestore;
Value = 1;
}]
then,
NSArray *resultArray=[responseSrting JSONValue];
NSMuatbleArray *keyArray=[[NSMutableArray alloc] init];
NSMutableArray *valueArray=[[NSMutableArray alloc] init];
for(NSDictionary *dict in resultsArray){
[keyArray addObject:[dict objectForKey:#"Key"]];
[valueArray addObject:[dict objectForKey:#"Value"]];
}
then, all your keys are stored in keyArray and all your values are stored in valueArray