I am working on an app which fetches data from a server. I convert this data to XML and then parse it using XMLDictionary. My problem is counting the number of objects inside the dictionary.
"finance_fee_collection" = (
{
amount = "790.00";
"due_date" = "2015-06-04";
name = "Third Payment";
},
{
amount = "790.00";
"due_date" = "2014-12-11";
name = "First Payment";
},
{
amount = "740.00";
"due_date" = "2015-07-06";
name = "third payment";
}
);
Counting the above number of objects yields 3, which is true. But counting the following also results 3.
"finance_fee_collection" = {
amount = "740.00";
"due_date" = "2015-07-06";
name = "third payment";
};
What I want is to count the number of "finance_fee_collection" items, such that the first one results 3 and the second one results 1. Is there anyway I can approach this goal?
The first one seems to be an array, the second a dictionary:
if([finance_fee_collection iskindOfClass:[NSDictionary class]]){
count = 1;
} else {
count = result.count;
}
something similar to this should work. :) hope it is helpful.
This doesn't make sense really, since both NSArray and NSDictionary implement the count method, which should return 3 for both structures:
id obj = #[#1 ,#2, #3]; // This is an NSArray
NSLog(#"%lu", (unsigned long)[obj count]); // Outputs 3
obj = #{ #1:#1,
#2:#2,
#3:#3
}; // now it's an NSDictionary
NSLog(#"%lu", (unsigned long)[obj count]); // Outputs 3
Were you using [object count] to get the count?
Either way, I wouldn't assume that count would be 1 simply because the data structure is a dictionary (you didn't count it)
Related
(
65,
61,
82,
{
FOMobilePhone = "";
FOName = "XXX";
FOTitle = "PRODUCTION DIRECTOR";
FOWorkEMail = "AAA#example.com";
FOWorkPhone = "+12345";
Id = 65;
},
{
FOMobilePhone = "";
FOName = "BBB";
FOTitle = "GSC EGYPT OPERATION LEAD";
FOWorkEMail = "BBB#example.com";
FOWorkPhone = "+12345";
Id = 61;
},
{
FOMobilePhone = "";
FOName = "CCC";
FOTitle = "PRODUCTION, DIRECTOR";
FOWorkEMail = "CCC#example.com";
FOWorkPhone = "+12345";
Id = 82;
}
}
First 3 items are IDs and remaining 3 arrays are their respective data. NSMutableArray has 6 (some example) items. 3 IDs and 3 arrays (info about those 3 IDs). How to remove those numbers (IDs)?
Let someArray = NSMUtableArray you are getting from server.
NSMutableIndexSet *discardedItems = [NSMutableIndexSet indexSet];
NSUInteger index = 0;
for (id someObject in someArray) {
if ([someObject isKindOfClass:[NSString class]]){
[discardedItems addIndex:index];
}
index++;
}
[someArray removeObjectsAtIndexes:discardedItems];
Finally , someArray will have only the data without IDs.
try this:
if NSMutableArray name is arr1 then you can do like this to remove three ID:
[arr1 removeObject:0];
[arr1 removeObject:1];
[arr1 removeObject:2];
You don't say what language you're using. If it's Swift, you could write a filter command that would get rid of the Int items.
If it's Objective-C you don't have that option, but you could do it various other ways. I'd suggest using filterUsingPredicate (if it's a mutable array) or filteredArrayUsingPredicate if it's an immutable array.
I'm using the Edmunds API to return a JSON string of vehicle makes for a certain year.
The resulting NSDictionary looks like this:
makes = (
{
id = 200002038;
models = (
{ // not relevant
}
);
name = Acura;
niceName = acura;
},
{
id = 200001769;
models = (
{ // not relevant
}
);
name = "Aston Martin";
niceName = "aston-martin";
},
There are a lot more values in this dictionary...how can I loop through through the dictionary to retrieve each of the 'name' values?
I like valueForKeyPath because you can do so much with it and it's a one line solution. Tested this and it works in my dev setup. If you know your data is in a predictable format, then you can do amazing things with valueForKeyPath.
NSArray *makeNames = [makes valueForKeyPath:#"name"];
Great info on valueForKeyPath http://nshipster.com/kvc-collection-operators/
NSMutableArray *makeNames = [NSMutableArray new];
for (NSDictionary *make in makes) {
NSLog(#"Make name: %#", make[#"name"]);
[makeNames addObject:make];
}
NSLog(#"Makes array: %#", makeNames);
I am having N number of Dictionaries & having array that contains objects.
I need to iterate and check whether value for key EmployeeID of dictionary exists at Object. say obj.empId or not in array.
Dictionary looks like below
{
"Message":[
{
"EmpID": 3749,
"Dept": 10,
"EmployeeName": "John",
},
{
},
{
}]
} //so many dictionaries..not one
Example: I already have an array with 10 records say obj.empID holds from 1-10. From service I am getting 10 records say 10 dictionaries. In that key EmpID holds values 5-15.
So, How can I iterate the loop so that to identify that new records are retrieved with different EmpID's then existing Records.
Here is the Code I have done so far..
NSArray *responseArray=responseDict[#"Message"];
for (NSDictionary *dict in responseDict[#"Message"]) {
for (id key in responseDict) {
if ([key isEqualToString:#"EmpID"]) {
for (Employees *empObj in emparray)
{
BOOL isExists=YES;;
if (![empObj.empid isEqualToString:[responseDict objectForKey:key]]) {
isExists=NO;
break;
//here I need to do the logic..
}
}
}
}
}
But it will not get accurate results or logic is nor correct..
Please suggest any better solutions for above task or where I am going wrong..
Any Ideas or suggestions are appreciated..
Thanks..,
Without using so many loops, you may follow below code to check record is exist ot not.
NSArray *responseArray=responseDict[#"Message"];
for (Employees *empObj in emparray)
{
BOOL isExists=NO;
if ([[responseArray valueForKey:#"EmpID"]containsObject:empObj.empid]) {
isExists=YES;
NSLog(#"%# EmpID Exist",empObj.empid);
//here I need to do the logic..
}else{
NSLog(#"%# EmpID Not Exist",empObj.empid);
}
}
Dont use iterations, Code smartly, Use following code...
NSArray *responseArray=responseDict[#"Message"];
NSArray * empIdResponseArray = [responseArray valueForKeyPath:#"#unionOfObjects.EmpID"];
NSArray * empIdLocalArray = [emparray valueForKeyPath:#"#unionOfObjects.empid"];
NSMutableSet *empIdResponseSet = [NSMutableSet setWithArray: empIdResponseArray];
NSSet *empIdLocalSet = [NSSet setWithArray: empIdLocalArray];
[empIdResponseSet intersectSet: empIdLocalSet];
NSArray *commonElementArray = [empIdResponseSet allObjects];
NSMutableArray *newElementArray = [NSMutableArray arrayWithArray:empIdResponseArray];
[newElementArray removeObjectsInArray:commonElementArray];
for (int index = 0; index < newElementArray.count; index++)
{
NSMutableDictionary * dictEmp = [NSMutableDictionary dictionaryWithDictionary:[newElementArray objectAtIndex:index]];
NSLog(#"EMPLOYEE = %#",dictEmp);
// Add your Logic for new records only....
// Enjoy :)
}
I have a NSArray containing multiple NSDictionary object and this NSDictionary again has one array of some NSStrings/NSNumbers...
This NSArray looks like below...
(
{
"bins_arr" = (
531662,
549177,
540165,
546616,
549777,
549778,
549779,
532663,
549852,
529495,
532662,
529117,
533890,
544170,
554619,
542418,
540175,
552137,
542531,
542556,
552093,
540531,
552790,
541497,
554637,
526421,
431921,
412800,
431922,
464558,
508159,
456822,
450900,
508126,
508125,
517700,
430463,
414746,
461797,
438628,
461796,
510460,
520386,
421175,
455038,
524133,
518936,
455390,
405450,
456407,
438587,
405451,
493714,
549149
);
"issuing_School" = ABCDEF;
status = 0;
title = ABCDEF;
},
{
"bins_arr" = (
429393,
416644,
416645,
416643,
416646,
436390,
436389,
436388,
470613,
524253,
428306,
489604,
478893,
414767,
428348,
469645,
421493,
470614,
543705
);
"issuing_School" = PQRS;
status = 0;
title = "PQRS";
},
{
"bins_arr" = (
422316,
421560,
483541
);
"issuing_School" = TCSB;
status = 0;
title = "TCSB";
}
)
Now I need to find out a given NString/NSNumber inside the NSArray, if it gets found I need to fine corresponding issuing_School value as well, for example If I find 461797 so it should search it and find that issuing_School of this is PQRS.
One way of doing it is to get the each NSArray inside NSArray-->NSDictionary and loop through the whole NSArray and match the given number with the number present and in the NSArray, but I don't want this search since this NSArray have so may object of NSDictionary and all NSDictionary object again have big NSArray.
Can Any one suggest me some awesome view to achieve this.
Thanks in Advance.
Turn your arrays into sets.
NSArray* array = ...;
NSSet* set = [[NSSet alloc] initWithArray:array];
if ([set containsObject:aNumber]) ...
No loop involved. Constant time no matter how many elements in the set.
I'm trying to get the nearby places using the foursquare api.
Here's the json data that is returned from
NSDictionary *results = [jsonString JSONValue];
NSLog(#"%#", results);
(
{
code = 200;
errorDetail = "This endpoint will stop returning groups in the future. Please use a current version, see http://bit.ly/lZx3NU.";
errorType = deprecated;
},
{
groups = (
{
items = (
{
categories = (
{
icon = "https://foursquare.com/img/categories/parks_outdoors/default.png";
id = 4bf58dd8d48988d163941735;
name = Park;
parents = (
"Great Outdoors"
);
pluralName = Parks;
primary = 1;
shortName = Park;
}
);
Then I try to get the list of the groups in an array with
NSArray *groups = [ (NSDictionary *)results objectForKey:#"groups"];
This returns the following error
2011-11-05 11:42:12.907 XperienzApp[1972:207] No of results returned: 0 Results : (null)
2011-11-05 11:42:13.225 XperienzApp[1972:207] -JSONValue failed. Error trace is: (
"Error Domain=org.brautaset.JSON.ErrorDomain Code=3 \"Unrecognised leading character\" UserInfo=0x5849cd0 {NSLocalizedDescription=Unrecognised leading character}"
)
2011-11-05 11:42:13.225 XperienzApp[1972:207] No of results returned: 0 Results : (null)
How should I parse this?
Edit:
I tried the suggested technique, this gives me an array
id groups = [[(NSDictionary *)results objectForKey:#"response"] objectForKey:#"groups"];
if ([results count] > 1){
NSLog(#"groups class %#\ngroups %# %d", groups, [groups class], [groups count]);
The log output is of the form:
{
categories = (
{
icon = "https://foursquare.com/img/categories/nightlife/danceparty.png";
id = 4bf58dd8d48988d11f941735;
name = Nightclub;
parents = (
"Nightlife Spots"
);
pluralName = Nightclubs;
primary = 1;
shortName = Nightclub;
}
);
contact = {
};
hereNow = {
count = 0;
};
id = 4eb33ba561af0dda8f673c1b;
location = {
address = "144 Willow St 4R";
city = Brooklyn;
crossStreet = Pierrepont;
distance = 462;
lat = "40.696864";
lng = "-73.996409";
postalCode = 11201;
state = NY;
};
name = "Entertainment 720, Ltd.";
stats = {
checkinsCount = 3;
tipCount = 0;
usersCount = 1;
};
verified = 0;
}
);
name = Nearby;
type = nearby;
}
)
groups __NSArrayM 1
This is again not json and is hard to parse, how do I get the output in json.
I'm the iPhone lead at foursquare. I'll try to take a stab at what's going on here.
First of all, I highly recommend you use JSONKit for your parser. It's lightweight and insanely fast: https://github.com/johnezang/JSONKit
It appears that you are parsing the JSON properly and getting the dictionary properly. Then you are logging the parsed object, not the original JSON. The output you are seeing is how Objective-C chooses to serialize the parsed dictionary to text. It is definitely not JSON. Using JSONKit, you could send the JSONString selector to your parsed result and convert it back to JSON and log that.
If you could provide some details on the problem you are trying to solve, I might be able to help you out more. And as Maudicus said, please pay attention to the error you are getting back. You don't want your app to break when we make the change to the API.
If the output below NSLog(#"%#", results); is your log statement. It appears your results variable is an array of dictionary objects.
Try to log the class of results to verify that NSLog(#"%#", [results class]);
If it is an array your groups object is the second object.
if ([results count] > 1)
id groups = [results objectAtIndex:1];
NSLog(#"groups class %#\ngroups %#", [groups class], groups);
Keep doing this until you understand the format of your data
Also the line
errorDetail = "This endpoint will stop returning groups in the future. Please use a current version, see http://bit.ly/lZx3NU.";
should be cause for concern. Check the documentation on foursquare for the current way of getting groups.