Find out a particular value from array of Dictionary - objective-c

I have an array which contains dictionary. In each dictionary again contains array of dictionary. I want figure out all the objects which has that particular value, like India.
I tried with NSpredicate. Example Array of dictionary
{
Destination : [
{
plan : [
{
name : "India"
},
{
name : "India"
}
]
},
{
plan : [
{
name : "Germany"
},
{
name : "Germany"
}
]
}
]
}
For this dictionary my code is
NSMutableArray * destinationArray = [[NSMutableArray alloc]init];
[destinationArray addObject:[ResponseObject objectForKey:#"Destination"]];
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",#"India"];
NSArray * filtered = [destinationArray filteredArrayUsingPredicate:predicate];

NSMutableArray* container = [NSMutableArray new];
for (NSMutableDictionary* d in firstArray) {
for (NSMutableDictionary* d2 in d[#"plan"]) {
[container addObject: [d2[#"name"] mutableCopy];
}
}
i believe this will do it

NSPredicate * predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",[[[ResponseObject objectAtIndex:i]objectForKey:#"destination"]objectForKey:#"name"]];
in your code, when call [[ResponseObject objectAtIndex:i]objectForKey:#"destination"] here return a NSArray contains some NSDictionary. when you call objectForKey:#"name", it will send you a error, are you sure you code is current?
here is my test follow your data struct, the result is current.
NSArray *array = #[#{#"name" : #"zhangsan",
#"age" : #"10",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
},
#{#"name" : #"lisi",
#"age" : #"11",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
},
#{#"name" : #"wangwu",
#"age" : #"12",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
}];
NSString *preStr = #"res";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[c] %#",preStr, #"123"];
NSMutableArray *result = [NSMutableArray array];
for (NSDictionary *dict in array) {
NSArray *res = dict[#"result"];
[result addObjectsFromArray:[res filteredArrayUsingPredicate:predicate]];
}
NSLog(#"final result == %#",result);

Related

Change json format in NSDictionary (Objective C)

I am new in ios programming. I should apply data to the chart. But the framework(ShinobiControls) which I use accepts only json with certain format. So I have to change my json data format to appropriate. I have NSDictionary which contain json like this:
"data": [
"01.01.2015",
"01.01.2015",
"01.01.2015",
"01.01.2015"]
"close": [
[
1,
1,
1,
1]
And now I should change format of the json like this:
[
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
}
]
I did some manipulation with converting NSDictionary to NSArray, but didn't get anything. How can I do it? Do you have any ideas? Thank you.
So if i understand your question right, you have a dictionary that contains 2 arrays and you want to convert it to an array that contains dictionaries , assuming that that the count of the arrays in the dictionary is equal, you can do the following
//This is the first array in your dictionary
NSArray * dataArr = [data objectForKey:#"data"] ;
//This the second array in your dictionary
NSArray * closeArr = [data objectForKey:#"close"] ;
NSUInteger dataCount = [dataArr count] ;
NSUInteger closeCount = [closeArr count] ;
//This will be your result array
NSMutableArray * newData = [NSMutableArray new] ;
//The loop condition checks that the current index is less than both the arrays
for(int i = 0 ; i<dataCount && i<closeCount ; i++)
{
NSMutableDictionary * temp = [NSMutableDictionary new] ;
NSString * dataString = [dataArr objectAtIndex:i];
NSString * closeString = [closeArr objectAtIndex:i];
[temp setObject:dataString forKey:#"date"];
[temp setObject:closeString forKey:#"close"] ;
[newData addObject:temp];
}
NSArray *Arr = [[NSArray alloc] initWithObjects:#"01.01.2015",#"01.01.2015",#"01.01.2015",#"02.01.2015", nil];
NSArray *Arr1 = [[NSArray alloc] initWithObjects:#"1",#"1",#"1",#"1", nil];
NSDictionary *Dic = [[NSDictionary alloc] initWithObjectsAndKeys:Arr,#"data",Arr1,#"close", nil];
NSLog(#"%#",Dic);
NSMutableArray *ArrM = [[NSMutableArray alloc] init];
for ( int i = 0; i<Arr.count; i++) {
NSDictionary *Dic = [[NSDictionary alloc] initWithObjectsAndKeys:Arr[i],#"data",Arr1[i],#"close", nil];
[ArrM addObject:Dic];
}
NSLog(#"%#",ArrM);
NSError * err;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:ArrM options:0 error:&err];
NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#",myString);

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;
}
);
}

Iterar over array of entity and get value of some key based on value of "other key" matche

I have an array of entity class (eg SubmittedAnswer). Its JSON format is look like as below.
{
"submittedAnswers": [{
"submittedQuestionId": "C7B3C4BE-CC3C-438F-A118-E798884A5FE0",
"serialNumber": 4,
"option": " it has a very large mass.",
"testQuestionId": "55230160-b905-47d5-a91c-e1dda6dd0634",
}, {
"submittedQuestionId": "9A6E9EA8-1BC0-4ED9-81E8-28B7E554D5E0",
"serialNumber": 1,
"option": " downward",
"testQuestionId": "fd0b3ae0-e999-48a6-89b8-a89b02e7b793",
}]
}
I want to find "option" field from that array whose "submittedQuestionId" is "something....". I dont want to use for loop.
Currently i am using following code.
NSString *submittedQuestionId = "something...."
int index = [[submittedAnswers valueForKey:#"submittedQuestionId"] indexOfObject:submittedQuestionId];
NSString *option = [[submittedAnswers valueForKey:#"option"] objectAtIndex:index];
I need better solution for this problem.
Assuming that submittedAnswers is an NSArray of NSDictionary objects, I found the answer here:
Stack Overflow > iPhone - Searching NSArray of NSDictionary objects
// Array `submittedAnswers` of sample data
NSArray* submittedAnswers = #[
#{
#"submittedQuestionId" : #"C7B3C4BE-CC3C-438F-A118-E798884A5FE0" ,
#"serialNumber" : #4 ,
#"option" : #" it has a very large mass." ,
#"testQuestionId" : #"55230160-b905-47d5-a91c-e1dda6dd0634" } ,
#{
#"submittedQuestionId" : #"9A6E9EA8-1BC0-4ED9-81E8-28B7E554D5E0" ,
#"serialNumber" : #1 ,
#"option" : #" downward" ,
#"testQuestionId" : #"fd0b3ae0-e999-48a6-89b8-a89b02e7b793" } ] ;
NSString *submittedQuestionId = #"9A6E9EA8-1BC0-4ED9-81E8-28B7E554D5E0" ;
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"submittedQuestionId = %#", submittedQuestionId] ;
NSArray* foundQuestions = [submittedAnswers filteredArrayUsingPredicate:predicate] ;
NSDictionary* foundQuestion = foundQuestions[0] ;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"submittedQuestionId == %#", yourSubmittedQuestionId];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
if ([filteredArray count] > 0) {
firstFoundObject = [filteredArray objectAtIndex:0];
}
Please make sure your SubmittedAnswer class has property submittedQuestionId

How can I filter an array of NSDictionarys and NSDictionarys?

I have an array which consists of several NSDictionaries with the keys:
NSString *name
NSString *ID
NSDictionary *phoneNumbersDict
Now I want to filter this array to find the one which has the phoneNumbersDict key #"keyIAmLookingFor" and the value #"valueIAmLookingFor".
NSMutableArray *addressBookPhoneIndividuals = [NSMutableArray array];
for (int i = 0; i < x; i++) {
[addressBookPhoneIndividuals addObject:#{
#"name" : #"...",
#"ID" : #"...",
#"phoneNumbers" : #{...}
}];
}
NSString *keyIAmLookingFor = #"work";
NSString *valueIAmLookingFor = #"444-567-9019";
NSArray *addressBookPhoneIndividuals = #[
#{
#"name" : #"Mike Rowe",
#"ID" : #"134",
#"phoneNumbers" : #{
#"work" : #"123-456-8000",
#"school" : #"647-5543",
#"home" : #"123-544-3321",
}
},
#{
#"name" : #"Eric Johnson",
#"ID" : #"1867",
#"phoneNumbers" : #{
#"work" : #"444-567-9019",
#"other" : #"143-555-6655",
}
},
#{
#"name" : #"Robot Nixon",
#"ID" : #"-12",
#"phoneNumbers" : #{
#"work" : #"123-544-3321",
#"school" : #"123-456-8000",
#"home" : #"444-567-9019",
}
},
];
NSString *keyPath = [#"phoneNumbers." stringByAppendingString:keyIAmLookingFor];
NSPredicate *predicate =
[NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:keyPath]
rightExpression:[NSExpression expressionForConstantValue:valueIAmLookingFor]
modifier:NSDirectPredicateModifier
type:NSEqualToPredicateOperatorType
options:0];
NSArray *result = [addressBookPhoneIndividuals filteredArrayUsingPredicate:predicate];
This will return an array containing the "Eric Johnson" dictionary.
I like to recommend NSComparisonPredicate when doing any kind of complex matching. Look at the options for modifier, type and options. There are some good built in matching engines in there - including regular expressions and case insensitivity. Anyway, it probably isn't necessary here, so you could substitute the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K = %#", keyPath, valueIAmLookingFor];
If you only care about the first result, you can skip the keyPath/predicate business altogether:
for (NSDictionary *individualDict in addressBookPhoneIndividuals) {
NSDictionary *phoneNumbers = [individualDict objectForKey:#"phoneNumbers"];
NSString *possibleMatch = [phoneNumbers objectForKey:keyIAmLookingFor];
if ([possibleMatch isEqualToString:valueIAmLookingFor]) {
return individualDict;
}
}
return nil;
You could use an NSPredicate to filter your array. Something like the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"phoneNumbers.keyIAmLookingFor == %#", #"valueIAmLookingFor"];
NSArray *matches = [addressBookPhoneIndividuals filteredArrayUsingPredicate:predicate];
I don't quite get how you want to filter your array, but one simple approach I use often is block-based filtering:
NSIndexSet* filteredIndexes = [addressBookPhoneIndividuals indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
NSString *name = [obj objectForKey:#"name"];
NSString *ID = [obj objectForKey:#"ID"];
NSDictionary *phoneNumbersDict = [obj objectForKey:#"phoneNumbersDict"];
return [[phoneNumbersDict objectForKey:#"keyIAmLookingFor"] isEqualToString:#"valueIAmLookingFor"];
}];
NSArray* filteredArray = [addressBookPhoneIndividuals objectsAtIndexes:filteredIndexes];
Does this help?
You can use
i. –allKeysForObject:
ii. –objectForKey:
iii. –valueForKey:
iv. –keysOfEntriesPassingTest:
v. –keysOfEntriesWithOptions:passingTest:
You can also go for NSPredicateFilter.

How to get specifying key's value array?

I'm trying to get array of just specifying key's value in following array obj.
Ex1) If specifying key "name",
wanted result is : {"James", "Jhone", "Michael", "Donald", "Mac"}
Ex2) If specifying key "age",
wanted result is : {25,27,35,25,26}
How to get?
Please help or advise.
NSArray *array = [[[NSArray alloc] initWithObjects:
#{#"name" : #"James", #"age" : #25},
#{#"name" : #"Jhone", #"age" : #27},
#{#"name" : #"Michael", #"age" : #35},
#{#"name" : #"Donald", #"age" : #25},
#{#"name" : #"Mac", #"age" : #26},
nil] autorelease];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"??? == name"];
NSArray *filtered = [array filteredArrayUsingPredicate:predicate];
NSLog(#"result : %#", filtered);
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"??? == age"];
NSArray *filtered = [array filteredArrayUsingPredicate:predicate];
NSLog(#"result : %#", filtered);
Give this a try:
[array valueForKey:specifyingKey]
Hope this helps!
Just use KVC.
[array valueForKey:#"age"]
should give you an array of the ages.