IOS Compare two array and get Result - ios

I have below JSON Format:
{
"Get_your_story_answer": [
{
"st_id": "19",
"story_title": "Newone",
"user_fb_id": "1649424812005217",
"winner_fb_id": "1685417121693688",
"winner_fb_id2": "",
"winner_fb_id3": "",
"story": "\ud83d\ude33\ud83d\ude25\ud83d\ude14\ud83d\ude0c",
"status": "1",
"s_created_date": "2016-01-18 23:06:05",
"reply_answer": [
{
"l_id": "42",
"story_id": "19",
"user_fb_id": "1649424812005217",
"selected_user_fb_id": "1685417121693688",
"answer": "hahaha",
"l_rating": "0",
"status": "1",
"l_created_date": "2016-01-18 23:10:51",
"l_new_created_date": "2016-01-19 11:40:51",
"winner": "1",
"answer_user_id": "3",
"answer_fb_id": "1685417121693688",
"answer_user_name": "Kin Patty"
},
{
"l_id": "43",
"story_id": "19",
"user_fb_id": "1649424812005217",
"selected_user_fb_id": "1498304680499454",
"answer": "",
"l_rating": "0",
"status": "1",
"l_created_date": "2016-01-18 23:06:05",
"l_new_created_date": "2016-01-19 11:36:05",
"winner": "0",
"answer_user_id": "10",
"answer_fb_id": "1498304680499454",
"answer_user_name": "John Kingman"
}
]
}
],
"status": "1",
"msg": "Get data"
}
Now I have to get Winner id
for Example "winner_fb_id" from [Get_your_story_answer] and compare it with [reply_answer].
If [reply_answer] contain "winner_fb_id" then I have to take only that name as winner .
Like in my Example , "Kin Patty"
I have tried this ,
//_getwind is mutable array
_getwinnerid =[NSMutableArray new];
_getwinnerid=[[_dataDictionary valueForKey:#"Get_your_story_answer"]valueForKey:#"winner_fb_id"];
Here is _getwinnerid output
<__NSArrayI 0x7ffb5a57c7b0>(
1685417121693688
NSArray *replaydata=[[_dataDictionary valueForKey:#"Get_your_story_answer"]valueForKey:#"reply_answer"];
Here is Replay Data Result
if (![replaydata containsObject:_getwinnerid]) {
NSLog(#"data");
}
Note:- Winner Id will be multiple. so, I have to compare 2 or more winner id and then take name from replay data response. And then I have to set name of winner in UITableview.

The value of Get_your_story_answer is an array, the requested data is in the first item of the array
NSDictionary *getYourStoryAnswer = _dataDictionary[#"Get_your_story_answer"][0];
Now get the winner ID and the array of answers
NSString *winnerID = getYourStoryAnswer[#"winner_fb_id"];
NSArray *answers = getYourStoryAnswer[#"reply_answer"];
Then enumerate the answers array (there are other solutions using blocks etc.)
for (NSDictionary *answer in answers) {
if ([answer[#"answer_fb_id"] isEqualToString: winnerID]) {
NSLog(#"%#", answer[#"answer_user_name"]);
break;
}
}
PS: Never use valueForKey to get one value for a key from a collection type unless you really need (and mean) the KVC method. The designated method is objectForKey or key subscription like above. valueForKey applied to an array returns always an array which is normally not intended.

for this you need to get total winner count from server.
like this.
int winnerCount = 3; //[Get_your_story_answer valueForKey:#"winner_count"];
Hopefully you have a fixed pattern key for winners like winner_fb_id, winner_fb_id1, winner_fb_id2 etc.
This will give you the desired result of winners name in array.
id response; // your response here
NSArray *array = [response objectForKey:#"Get_your_story_answer"];
NSDictionary *Get_your_story_answer = array[0];
NSMutableArray *winnersArray = [[NSMutableArray alloc] init];
int winnerCount = 3; //[Get_your_story_answer valueForKey:#"winner_count"];
for (int i = 0; i< winnerCount; i++) {
NSString *winnerId = nil;
if(i != 0){
winnerId = [Get_your_story_answer valueForKey:[NSString stringWithFormat:#"winner_fb_id%d",i]];
}
else{
winnerId= [Get_your_story_answer valueForKey:[NSString stringWithFormat:#"winner_fb_id"]];
}
if(winnerId)
{
[winnersArray addObject:winnerId];
}
}
__block NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSArray *replyAnswers = [Get_your_story_answer objectForKey:#"reply_answer"];
[replyAnswers enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
NSString *answer_fb_id = [obj valueForKey:#"answer_fb_id"];
[winnersArray enumerateObjectsUsingBlock: ^(NSString * winnerId, NSUInteger idx, BOOL *stop) {
if([winnerId isEqualToString:answer_fb_id]){
// get name of winner
[resultArray addObject:[obj valueForKey:#"answer_user_name"]];
}
}];
}];
// Your name of wiiners are in resultArray.

I have filtered array using the answer as said by larme Thank you.
NSError *errorJSON = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&errorJSON];
if (!errorJSON)
{
NSDictionary *storyAnwser = [json[#"Get_your_story_answer"] firstObject];
NSArray *allAnswersKeys = [storyAnwser allKeys];
NSArray *allWinnersKeys = [allAnswersKeys filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString * _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject hasPrefix:#"winner_fb_id"];
}]];
NSLog(#"AllWinnersKeys: %#", allWinnersKeys);
NSArray *allWinnersIds = [storyAnwser objectsForKeys:allWinnersKeys notFoundMarker:[NSNull null]];
NSLog(#"AllWinnersIds: %#", allWinnersIds);
NSArray *allAnswers = storyAnwser[#"reply_answer"];
NSLog(#"AllAnswers: %#", allAnswers);
NSArray *allWinners = [allAnswers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"answer_fb_id IN %#", allWinnersIds]];
NSLog(#"allWinners: %#", allWinners);
NSArray *allWinersNames = [allWinners valueForKey:#"answer_user_name"];
NSLog(#"AllWinnersNames: %#", allWinersNames);
}
else
{
NSLog(#"Error JSON: %#", errorJSON);
}

Related

Merging Two Arrays with Same Index in Objective C

I want to Merge Two Array With Same Index,
This is my JSON
"tier_info": [
{
"tier_id": "1",
"tier_name": "tier-1",
"price": "3.9",
"ios_id": "tier-1",
"android_id": "tier-1"
},
{
"tier_id": "2",
"tier_name": "tier-2",
"price": "4.9",
"ios_id": "tier-2",
"android_id": "tier-2"
},
{
"tier_id": "3",
"tier_name": "tier-3",
"price": "5.9",
"ios_id": "tier-3",
"android_id": "tier-3"
},
{
"tier_id": "4",
"tier_name": "free",
"price": "0",
"ios_id": "free",
"android_id": "free"
}
]
I'm using custom picker, Now I want "tier_name" with "price" in same array index [e.g. "tier_1 : 3.9"].
Code of merging two Array:
NSMutableArray *tierTitles = [[NSMutableArray alloc] init];
tierTitles = [tierArray valueForKey:#"tier_name"];
NSMutableArray *tierPrice = [[NSMutableArray alloc] init];
tierPrice = [tierArray valueForKey:#"price"];
NSMutableArray *combined = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < tierArray.count; i++) {
[combined addObject: #{tierTitles[i]:tierPrice[i]}];
}
and i got this
(
{
"tier-1" = "3.9";
},
{
"tier-2" = "4.9";
},
{
"tier-3" = "5.9";
},
{
free = 0;
}
)
i want it like :
(
"tier-1" = "3.9";
"tier-2" = "4.9";
"tier-3" = "5.9";
free = 0;
)
what am i doing wrong here..any correct way to do this?
I think what you're asking is you need an NSDictionary that contains both name and price as key-value.You need to enumerate each object and add it to an array if the value exist :-
NSMutableArray *results=[NSMutableArray new];
for (NSDictionary *tier in tierArray]) {
if ([tier[#"tier_name"] length] && [tier[#"price"] length]) {
[results addObject:#{tier[#"tier_name"]:tier[#"price"]:}];
}
}
Or create a Mutable Dictionary Like this:-
NSMutableDictionary *results=[NSMutableDictionary new];
for (NSDictionary *tier in tierArray) {
if ([tier[#"tier_name"] length] && [tier[#"price"] length]) {
[results setValue:tier[#"price" forKey:tier[#"tier_name"]];
}
}
I think you should add dictionary to your combined array like as below
[tierTitles enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSMutableDictionary*combinedDict = [[NSMutableDictionary alloc]init];
[combinedDict setValue:[tierPrice objectAtIndex:idx] forKey:obj];
[combined addObject: combinedDict];
}];

Parsing JSON Object - Objective C

I'm struggling to see why this code is not working. I have many other views using different JSON services. All working normally. However, this one is simply not. I retrieve the values back from the service as I expect however when trying to loop over it (see below code) the Array is Nil. Clearly something simple I have missed but I have been looking at this issue far to long.
Abstract View of JSON service;
{
"0": {
"altitude": "14500",
"latitude": "41.41555",
"longitude": "-73.09605",
"realname": "David KGNV"
},
"1": {
"altitude": "61",
"latitude": "33.67506",
"longitude": "-117.86739",
"realname": "Mark CT"
},
"10": {
"altitude": "38161",
"latitude": "40.51570",
"longitude": "-93.25554",
"realname": "Bob CYYZ"
},
"100": {
"altitude": "33953",
"latitude": "52.35600",
"longitude": "5.30384",
"realname": "Jim LIRQ"
}
}
Abstract view of the JSON call;
*Note the NSArray *currentMapArray valueKeyPath is set to "" as I need all elements within the JSON result.
NSError *_errorJson = nil;
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if (_errorJson != nil) {
NSLog(#"Error %#", [_errorJson localizedDescription]);
} else {
//Do something with returned array
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *mapJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//Loop through the JSON array
NSArray *currentMapArray = [mapJson valueForKeyPath:#""];
//set up array and json call
mapArray = [[NSMutableArray alloc]init];
for (int i = 0; i< currentMapArray.count; i++)
{
//create our object
NSString *nAltitude = [[currentMapArray objectAtIndex:i] objectForKey:#"altitude"];
NSString *nRealname = [[currentMapArray objectAtIndex:i] objectForKey:#"realname"];
NSString *nLatitude = [[currentMapArray objectAtIndex:i] objectForKey:#"latitude"];
NSString *nLongitude = [[currentMapArray objectAtIndex:i] objectForKey:#"longitude"];
[mapArray addObject:[[LiveVatsimMap alloc]initWithaltitude:nAltitude andrealname:nRealname andlatitude:nLatitude andlongitude:nLongitude]];
}
The results of currentMapArray is NIL resulting the NSString not being filled out appropriately.
for (int i = 0; i< currentMapArray.count; i++)
Of course when I hard code the value of JSON node i.e. 10 into the ValueKeyPath then it provides the correct data results and populates accordingly.
Any ideas? Be nice...I'm only new at this objective c stuff.
Your JSON doesn't have an array - it is a dictionary of dictionaries.
You can iterate over it using
NSArray *keys=[jsonArray allKeys];
for (NSString *key in keys) {
NSDictionary *elementDictionary=jsonArray[key];
NSString *nAltitude = elementDictionary[#"altitude"];
NSString *nRealname = elementDictionary[#"realname"];
NSString *nLatitude = elementDictionary[#"latitude"];
NSString *nLongitude = elementDictionary[#"longitude"];
[mapArray addObject:[[LiveVatsimMap alloc]initWithaltitude:nAltitude andrealname:nRealname andlatitude:nLatitude andlongitude:nLongitude]];
}

Parsing values from NSArray based on JSON format

I have a NSArray which is based on JSON format. I requested it from the web and saved it in the array. I am trying to use a dictionary to get the values of "categoryname" and "subscore" and store them in new arrays, but they remain empty. Do I have to convert the array back to NSData using JSON serialisation or is there a more direct way to achieve this?
NSArray detailedscore:
{
"articles": [
{
"abstract": "text",
"title": "title"
}
],
"subscore": 3,
"categoryname": "Reporting"
},
{
"articles": [
{
"abstract": "text2",
"title": "title"
}
],
"subscore": 1,
"categoryname": "Power"
}]
}
Code:
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores addObject:subscore];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
{} ----> means dictionary, []---> array..... this is a rule I follow while assinging the return value from webservices as NSArray or NSDictionary....
Depending on your current JSON format, perhaps this might give you an idea
NSMutableArray *categoryArray = [NSMutableArray new];
for (NSDictionary *childDict in self.detailedscore)
{
[categoryArray addObject:[childDict objectForkey:#"categoryname"]];
}
If you have the array use below code
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores score];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
The problem wasn't in the array or dictionary or the web request. I didn't allocated the NSMutableArrays so they were empty all the time. The code works fine for extracting values from the array in case anyone wants to use it.
Hope this helps.
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&connectionError];
NSLog(#"Dict %#",dict);
BOOL isValid = [NSJSONSerialization isValidJSONObject:dict];
if (isValid) {
[target getJSONFromresponseDictionary:dict forConnection:strTag error:connectionError];
}
else{
NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[target getStringFromresponseDictionary:strResponse forConnection:strTag error:error];
}

create array which is filtered from array of dictionary with the array as a input

I have one dictionary and one array as shown below
Dictionary :
{
"value": [
{
"ctgid": "1",
"catename": "tow"
},
{
"ctgid": "2",
"catename": "towrequest"
},
{
"ctgid": "3",
"catename": "electrical"
},
{
"ctgid": "5",
"catename": "plumber"
},
{
"ctgid": "6",
"catename": "maintenance"
},
{
"ctgid": "7",
"catename": "home"
},
{
"ctgid": "8",
"catename": "computer"
},
{
"ctgid": "9",
"catename": "1q2w"
}
]
}
Array of catename:
(
tow,
towrequest,
plumber
)
There is a list of catename in Array.From above dictionary I want to create the array of ctgid related to catename in above array.
So my final output should be :
Array of catgid :
(
1,
2,
5
)
Note : I can do it with loop , but I don't want to use any loop.
//Json data
NSString *jsonString = #"{\"value\":[{\"ctgid\":\"1\",\"catename\":\"tow\"},{\"ctgid\":\"2\",\"catename\":\"towrequest\"},{\"ctgid\":\"3\",\"catename\":\"electrical\"},{\"ctgid\":\"5\",\"catename\":\"plumber\"},{\"ctgid\":\"6\",\"catename\":\"maintenance\"},{\"ctgid\":\"7\",\"catename\":\"home\"},{\"ctgid\":\"8\",\"catename\":\"computer\"},{\"ctgid\":\"9\",\"catename\":\"1q2w\"}]}";
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
//Converting the data into NSDictionary
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//Get the array of objects
NSArray *array = [NSArray arrayWithArray:[json objectForKey:#"value" ]];
//Category filter names
NSArray *filteCatename = [NSArray arrayWithObjects:#"tow",#"towrequest",#"plumber",nil];
//NSPreicate to filter the array using "in" constrain
NSArray *filtered = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(catename in %#)", filteCatename]];
You can use NSPredicate to filter the NSArray directly without loop.
it is too late, though i put an answer hope this could help ..
[dictArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //dictArray is an array contains your "value"
if([arrCatename containsObject:[obj objectForKey:#"catename"]]) //arrCatename is array contains catename list
{
[arrCatid addObject:[obj objectForKey:#"ctgid"]]; //arrCatid is the result
}
}];
NSLog(#"%#",arrCatid.description);
I haven't tested , but hopefully this is it .
NSMutableArray *arrCatID = [NSmutableArray alloc]init];
for (NSDictionary *instance in myDictionary){ // myDictionary is the values of "Value"
NSString *content = [instance objectForKey:#"catename"];
for (NSString *catName in stringArray) { // stringArray --> has already the CatNAmes with you
if (catName == content) {
[arrCatID addObject:[instance objectForKey:#"ctgid"];
break;
}
}
}

How can I get the JSON array data from nsstring or byte in xcode 4.2?

I'm trying to get values from nsdata class and doesn't work.
here is my JSON data.
{
"count": 3,
"item": [{
"id": "1",
"latitude": "37.556811",
"longitude": "126.922015",
"imgUrl": "http://175.211.62.15/sample_res/1.jpg",
"found": false
}, {
"id": "3",
"latitude": "37.556203",
"longitude": "126.922629",
"imgUrl": "http://175.211.62.15/sample_res/3.jpg",
"found": false
}, {
"id": "2",
"latitude": "37.556985",
"longitude": "126.92286",
"imgUrl": "http://175.211.62.15/sample_res/2.jpg",
"found": false
}]
}
and here is my code
-(NSDictionary *)getDataFromItemList
{
NSData *dataBody = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
NSDictionary *iTem = [[NSDictionary alloc]init];
iTem = [NSJSONSerialization JSONObjectWithData:dataBody options:NSJSONReadingMutableContainers error:nil];
NSLog(#"id = %#",[iTem objectForKey:#"id"]);
//for Test
output = [[NSString alloc] initWithBytes:buffer length:rangeHeader.length encoding:NSUTF8StringEncoding];
NSLog(#"%#",output);
return iTem;
}
how can I access every value in the JSON? Please help me.
look like this ..
NSString *jsonString = #"your json";
NSData *JSONdata = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
if (JSONdata != nil) {
//this you need to know json root is NSDictionary or NSArray , you smaple is NSDictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:JSONdata options:0 error:&jsonError];
if (jsonError == nil) {
//every need check value is null or not , json null like ( "count": null )
if (dic == (NSDictionary *)[NSNull null]) {
return nil;
}
//every property you must know , what type is
if ([dic objectForKey:#"count"] != [NSNull null]) {
[self setCount:[[dic objectForKey:#"count"] integerValue]];
}
if ([dic objectForKey:#"item"] != [NSNull null]) {
NSArray *itemArray = [dic objectForKey:#"item"]; // check null if need
for (NSDictionary *itemDic in itemArray){
NSString *_id = [dic objectForKey:#"id"]; // check null if need
NSNumber *found = (NSNumber *)[dic objectForKey:#"found"];
//.....
//.... just Dictionary get key value
}
}
}
}
I did it by using the framework : http://stig.github.com/json-framework/
It is very powerfull and can do incredible stuff !
Here how I use it to extract an item name from an HTTP request :
(where result is the JSO string)
NSString *result = request.responseString;
jsonArray = (NSArray*)[result JSONValue]; /* Convert the response into an array */
NSDictionary *jsonDict = [jsonArray objectAtIndex:0];
/* grabs information and display them in the labels*/
name = [jsonDict objectForKey:#"wine_name"];
Hope this will be helpfull
Looking at your JSON, you are not querying the right object in the object hierarchy. The top object, which you extract correctly, is an NSDictionary. To get at the items array, and the single items, you have to do this.
NSArray *items = [iTem objectForKey:#"item"];
NSArray *filteredArray = [items filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"id = %d", 2];
if (filteredArray.count) NSDictionary *item2 = [filteredArray objectAtIndex:0];
Try JSONKit for this. Is is extremely simple to use.
Note sure if this is still relevant, but in iOS 5, apple added reasonable support for JSON. Check out this blog for a small Tutorial
There is no need to import any JSON framework. (+1 if this answer is relevant)

Resources