Comparing Dictionaries with Objects Value of Array in IOS - ios

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

Related

Parsing JSON with NSDictionary

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)

Getting values from key in NSDictionary

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

iOS sort one array based on order of strings in another array

This is another very specific problem I am trying to solve.
I am pulling a list a twitter user accounts logged into the users settings application. This returns an array with the usernames in the correct order.
I then pass this array to this twitter API:
https://api.twitter.com/1.1/users/lookup.json
The returned array contain all the additional data I need for each user account logged in. The first array contains NSStrings (usernames), the returned array has been parsed to contain dictionaries that have a key and value for the username, name, and profile pic.
Problem now is that the order is completely different than the first array I passed.. This is expected behavior from Twitter, but it needs to be in the exact same order (I will be referencing the original index of the AccountStore which will match the first array, but not the new array of dictionaries).
How can I tell the new array to match the contained dictionaries to be the same order as the first array based on the username key?
I know this sounds confusing, so let me at least post the data to help.
Here is the first array output:
(
kbegeman,
indeedyes,
soiownabusiness,
iphonedev4me
)
Here is what the second array outputs:
(
{
image = "https://si0.twimg.com/profile_images/3518542448/3d2862eee546894a6b0600713a8de862_normal.jpeg";
name = "Kyle Begeman";
"screen_name" = kbegeman;
},
{
image = "https://si0.twimg.com/profile_images/481537542/image_normal.jpg";
name = "Jane Doe";
"screen_name" = iPhoneDev4Me;
},
{
image = "https://twimg0-a.akamaihd.net/profile_images/378800000139973355/787498ff5a80a5f45e234b79005f56b5_normal.jpeg";
name = "John Doe";
"screen_name" = indeedyes;
},
{
image = "https://si0.twimg.com/sticky/default_profile_images/default_profile_5_normal.png";
name = "Brad Pitt";
"screen_name" = soiownabusiness;
}
)
Due to the way Twitter returns the data, it is never the EXACT same order, so I have to check this every time I call these methods.
Any help would be great, would save my night. Thanks in advance!
You want the array of dictionaries be sorted by comparing screen_name value with your first array. Right? Also, the screen name may have different case than your username. Right?
I would use mapping dictionary:
Create dictionary from screen name to user dictionary:
NSArray *screenNames = [arrayOfUserDicts valueForKeyPath:#"screen_name.lowercaseString"];
NSDictionary *userDictsByScreenName = [NSDictionary dictionaryWithObjects:arrayOfUserDicts forKeys:screenNames];
Build final array by finding user dictionary for usernames in your array:
NSMutableArray *sortedUserDicts = [NSMutableArray arrayWithCapacity:arrayOfUsernames.count];
for (NSString *username in arrayOfUsernames) {
NSDictionary *userDict = [userDictsByScreenName objectForKey:username.lowercaseString];
[sortedUserDicts addObject:userDict];
}
First generate a mapping that maps the "screen_name" to the corresponding dictionary
in the second array:
NSDictionary *map = [NSDictionary dictionaryWithObjects:secondArray
forKeys:[secondArray valueForKey:#"screen_name"]];
Then you can create the sorted array with a single loop:
NSMutableArray *sorted = [NSMutableArray array];
for (NSString *name in firstArray) {
[sorted addObject:map[name]];
}
That sort order isn't something that could be easily replicated (i.e. it's not alpha, etc). Instead, you should just use that original NSArray as a guide to match data from the NSDictionary from Twitter. For example:
[twitterDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSInteger index = [yourLocalArray indexOfObject:obj];
if (index != NSNotFound) {
// You have a match, do something.
}
}];
lets name your arrays as firstArray and secondArray.
NSArray *sortedArray = [secondArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [#([firstArray indexOfObject:[obj1 objectForKey:#"name"]]) compare:#([firstArray indexOfObject:[obj2 objectForKey:#"name"]])];
}];

iOS filter array of dictionary base on value and not the key

I have array with dictionaries like this:
Array: (
{
customerUS= {
DisplayName = "level";
InternalName = "Number 2";
NumberValue = 1;
},
customerCAN= {
DisplayName = "PurchaseAmount";
InternalName = "Number 1";
NumberValue = 3500;
};
}
)
I want to filter the dictionaries base on particular value and not the key. For example I want all the dictionaries with values on any key of 3500. Does any body knows how can I do this?
I'll really appreciate your help.
Try a predicate format like:
#"%# IN SELF", testValue
When you filter the array each will be run against the IN. When you pass IN a dictionary it uses the values of the dictionary.
you can also use
-keysOfEntriesPassingTest:
of NSDictionary. Just pass in a block like so:
for(NSDictionary *myDictionary in myArray){
NSSet *resultSet = [myDictionary keysOfEntriesPassingTest:^(id key, id object, BOOL *stop) {
//assuming that 3500 is an int, otherwise use appropriate condition.
if([[NSNumber numberWithInt:object] isEqual:[NSNumber numberWithInt:3500]]){
return YES;
}else{
return NO;
}
}];
if (resultSet.count>0){
//do whatever to myDictionary
}
}

Add data from an array using its value for key to another Array

Hi i have two Arrays one being Parsed Data that has multiple entries at each cell (FolderName & ID) i want this data to be saved into another array like it is stored in the first array
FilteredData = [[NSMutableArray alloc]initWithArray:[ParsedData ValueForKey:#"FolderName"]];
SearchData = [[NSMutableArray alloc]initWithArray:FilteredData];
This is what i have been trying, The data Containing a dictionary at each entry is ParsedData, And the Array in which i have to copy these items is SearchData.
The Array (Parsed Data) Containing the dictionary looks like this
PARSED DATA (
{
CreatedBy = 1;
FolderName = Posteingang;
ID = 13000;
ParentID = 0;
},
{
CreatedBy = 1;
FolderName = Freigaben;
ID = 13001;
ParentID = 0;
},
From this Array I need to Get the FolderName And the ID and get them in the SearchData Array
SearchData (
Posteingang;
13000;
Freigaben;
13001;
)
I hope the question is clear now
check this one,
NSMutableArray *searchData = [NSMutableArray new];
for(NSDictionary *dict in ParsedDataArray){//here ParsedDataArray means PARSED DATA array name
NSDictionary *tempDict=[[NSDictionary alloc]initWithObjectsAndKeys:[dict ValueForKey:#"FolderName"],#"FolderName",[dict ValueForKey:#"ID"],#"ID" nil],
[searchData addObject:dict];
}
It seems like you misspelled the method name, it should be:
dictionaryWithObjectsAndKeys:
Notice the "s" after Object.
I want a dictionary inside an array which contains foldername and id
So you can get it using this:
NSMutableArray *searchData = [NSMutableArray new];
for(NSDictionary *dict in parsedDataArray){
NSDictionary *tempDict=#{#"FolderName":dict[#"FolderName"],
#"ID":dict[#"ID"]};
[searchData addObject:tempDict];
}
EDIT:
#[#"key:#"object"] is the new dictionary literal.
If you are using Xcode 4.3 or older need to do as:
NSDictionary *tempDict=#{#"FolderName":dict[#"FolderName"],
#"ID":dict[#"ID"]};
means,
NSDictionary *tempDict=[NSDictionary dictionaryWithObjectsAndKeys:[dict objectForKey:#"FolderName"], #"FolderName",[dict objectForKey:#"ID"],#"ID", nil];

Resources