How to compare two dictionary - iphone

I have two array of dictionaries and i want to compare them
Actually the dictionary structure is like the interest list of Facebook, like below
I want to find out the common interest between me and my friend
I retrieved the interest list of both user, but while I am comparing the dictionary of interests as the created_time differs so I am not getting the common dictionary
category = "Musical instrument";
"created_time" = "2011-06-11T09:10:07+0000";
id = 113099055370169;
name = Guitar;
and
category = "Musical instrument";
"created_time" = "2013-09-27T06:02:28+0000";
id = 113099055370169;
name = Guitar;
Can anybody suggest any efficient way to do this
Now I am using but it is not giving me the common interests as created_time different
for (int count = 0; count < [arrFriendsInterest count]; count++)
{
NSDictionary *dictFriend = [arrFriendsInterest objectAtIndex:count];
if ([arrMyIntrest containsObject:dictFriend]) {
[arrMutualInterest addObject:dictFriend];
}
}
where arrFriendsInterest is array of dictionaries containing friend's interest
and arrMyIntrest is the array of dictionaries containing my interests×Comments may only be edited for 5 minutes×Comments may only be edited for 5 minutes×Comments may only be edited for 5 minutes

First of all are you store that data in NSArray?
If YES then please use following code much more easily to use.
// Do any additional setup after loading the view, typically from a nib.
NSArray *ar1 = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:#"Musical instrument",#"category",#"2011-06-11T09:10:07+0000",#"created_time",#"113099055370169",#"id", #"Guitar",#"name", nil], nil];
NSArray *ar2 = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:#"Musical instrument",#"category",#"2013-09-27T06:02:28+0000",#"created_time",#"113099055370169",#"id", #"Guitar",#"name", nil], nil];
NSMutableSet* set1 = [NSMutableSet setWithArray:ar1];
NSMutableSet* set2 = [NSMutableSet setWithArray:ar2];
[set1 unionSet:set2]; //this will give you only the obejcts that are in both sets
NSArray* result = [set1 allObjects];
NSLog(#"%#",[result mutableCopy]);
Happy Coding.!!!

This assumes that you only need to compare "id" values:
NSArray* myIds = [arrMyInterest valueForKey:#"id"];
for (int count = 0; count < [arrFriendsInterest count]; count++) {
NSDictionary *dictFriend = [arrFriendsInterest objectAtIndex:count];
// Not clear whether "id" is NSString or NSNumber -- use whichever
NSString* friendId = [dictFriend valueForKey:#"id"];
if ([myIds containsObject:friendId]) {
[arrMutualInterest addObject:dictFriend];
}
}

instead of using NSDictionary why don't using custom classes?
You can have a lot of benefits:
code completion
compile-time checking
custom isEqual method
code is self-explained

Related

Delete only one item from array having same multiple values

There is an array in my app having multiple same values in it. I need to delete only one value at a time from array whether it has same more values in it.
Level1 Business,
Level2 Economy,
Level2 Economy,
Level1 Business
How this can be achieved, and main thing is that these values are dynamic these can be more or less also. Please guide for above.
Below is what i tried.
if([arr containsObject:[NSString stringWithFormat:#"%d",ind]]){
[arr removeObject:[NSString stringWithFormat:#"%d",ind]];
}
This thing removes all similar entries, not required. Thanks in advance.
try like this,
NSArray *array = [NSArray arrayWithObjects:#"Level1 Business", #"Level2 Economy", #"Level2 Economy", #"Level1 Business", nil];
NSMutableArray *mainarray=[[NSMutableArray alloc]initWithArray:array];
int n=[mainarray indexOfObject:#"Level2 Economy"];//it gives first occurence of the object in that array
if(n<[mainarray count]) // if the object not exist then it gives garbage value that's why here we have to take some condition
[mainarray removeObjectAtIndex:n];
NSLog(#"%#",mainarray);
O/P:-
(
"Level1 Business",
"Level2 Economy",
"Level1 Business"
)
As you say,
[array removeObject:#"SomeObject"];
removes all instances of where isEqual: returns YES. To remove only the first instance, you can use something like
NSUInteger index = [array indexOfObject:#"SomeObject"];
if(index != NSNotFound) {
[array removeObjectAtIndex:index];
}
Use [arr removeObjectAtIndex:yourIndex ] to remove your object at perticular postion at dynamic
Sample Code :
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:#"hello",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",nil];
NSUInteger obj = [arr indexOfObject:#"hi"]; //Returns the lowest integer of the specified object
[arr removeObjectAtIndex:obj]; //removes the object from the array
NSLog(#"%#",arr);
In your Case :
if([arr containsObject:[NSString stringWithFormat:#"%d",ind]])
{
NSUInteger obj = [arr indexOfObject:[NSString stringWithFormat:#"%d",ind]]; //Returns the lowest integer of the specified object
[arr removeObjectAtIndex:obj];
}
Here your requirement is like definition of NSSet, which contains unique objects only.
But this will implies only if both the same value objects, are really in referring to same memory location as well.
If this is the case then and then, you can try code mentioned below:
// create set from an array
NSSet *telephoneSet = [NSSet setWithArray: myArray];
// create array from a set
NSMutableArray *array = [NSMutableArray arrayWithArray:[set allObjects]];
I don't know whether it will work for your requirement or not. But for that, it would be required to check the object equality level.
Still it might help you as an less line of code.
NSMutableArray *uniques= [[NSMutableArray alloc] init];
for (NSString *word in duplicateWordsArray){
if (!uniques.contains(word)){
[ uniques addObject:word];
}
}
I wrote this from my phone so it isn't formatted for code, but this will do it for you quickly and you'll have an array (uniquearray) that has unique words. Then you can use that one or set your original array = to unique array
NSArray *input = [NSArray arrayWithObjects:#"Level1 Business", #"Level2 Economy", #"Level2 Economy", #"Level1 Business", nil];
NSMutableArray *output = [[NSMutableArray alloc] init];
[output addObject:[input objectAtIndex:0]];
for(NSString *value in input) {
if(![output containsObject:value])
[output addObject:value];
}

Sorting Multiple NSMutableArray's

I have 3 MutableArray's Named:
tvShows
tvNetworks
tvdbID
I need to sort them by the name of the tvShows.
But the need to stay linked.
So e.g.:
tvShows = Breaking Bad, House, Community;
tvNetworks = AMC, FOX, NBC;
tvdbID = 81189, 73255, 94571;
Needs To Become:
tvShows = Breaking Bad, Community, House;
tvNetworks = AMC, NBC, FOX;
tvdbID = 81189, 94571, 73255;
How would I do this? It's my first app so sorry if it's a realy easy question.
store them in an array of dictionaries then sort with an NSArray sort function: (below)
NSDictionary * dict1 = #{#"title":#"breaking bad",#"network":#"AMC",#"tvbdID":#(81189)};
NSDictionary * dict2 = #{#"title":#"house",#"network":#"FOX",#"tvbdID":#(73255)};
NSDictionary * dict3 = #{#"title":#"Community",#"network":#"NBC",#"tvbdID":#(94571)};
NSArray * array = #[dict1,dict2,dict3];
NSSortDescriptor * desc = [NSSortDescriptor sortDescriptorWithKey:#"title"ascending:YES selector:#selector(caseInsensitiveCompare:)];
NSArray * sortedArray = [array sortedArrayUsingDescriptors:#[desc]];
I would personally create a custom NSObject called TVShow, that has properties of showName, network, and tvbdID. This way, you only have one array of each show. Assuming your array is called myShows, you could do something like this:
[allShows sortUsingComparitor:^NSComparisonResult(id a, id b) {
NSString *firstName = [(TVShow*)a showName];
NSString *secondName = [(TVShow*)b showName];
return [firstName compare: secondName];
}];
That is, if you wanted to sort by show name. You can swap network for showName if you wanted to sort by network!
No idea what your end goal is, but you should probably create a TVShow class that has properties (i.e., instance variables) for "title," "network", and "dbid." Then you can instantiate three TVShow objects with their appropriate properties, put them in a mutable array, and use one of the sorting methods on NSMutableArray -- I'd probably choose sortUsingComparator:.
you can't do it with 3 independent arrays but maybe with 1 dictionary where the keys are tv shows and the value is a dictionary with 2 keys: tvNetworks & tvdbIDs
sample:
NSDictionary *data = #{#"Breaking Bad":#{#"tv" : #"AMC", #"tvdb": #(81189)},
#"House":#{#"tv" : #"FOX", #"tvdb": #(73255)},
#"Community":#{#"tv" : #"NBC", #"tvdb": #(94571)}};
NSArray *sortedShows = [data.allKeys sortedArrayUsingSelector:#selector(compare:)];
for (id show in sortedShows) {
NSLog(#"%# = %#", show, data[show]);
}
One of the easiest and most straightforward ways to do this would be to create one array of dictionaries, like this:
NSMutableArray *tvShowInfos = [NSMutableArray array];
for (NSInteger i = 0; i < tvShows.count; i++) {
NSDictionary *info = #{#"show": [tvShows objectAtIndex:i],
#"network": [tvNetworks objectAtIndex:i],
#"id": [tvdbIDs objectAtIndex:i]};
[tvShowInfos addObject:info];
}
You can then sort that array easily:
[tvShowInfos sortUsingDescriptors:#[ [[NSSortDescriptor alloc] initWithKey:#"show" ascending:YES] ]];
If you need an array that contains all networks, sorted by show title, you can then use valueForKey: on the array of dictionaries:
NSArray *networksSortedByShow = [tvShowInfos valueForKey:#"network"];

How to create an array with particular item from a dictionary?

I have an application in which i am having the details of the members as a dictionary.i want to add an array with particular object from the dictionary.The response i am having is like this,
{
500 = {
name = baddd;
status = "<null>";
};
511 = {
name = abyj;
status = "Hi all...:-)";
};
512 = {
name = abyk;
status = fdffd;
};
}
I want to create an array with the results of name only.i have tried like this
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSString *name=[NSString stringWithFormat:#"%#",[self.currentChannel.members objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
but the value added is null. can anybody help me ?
Traverse objectEnumerator to get the values (inner dictionaries). Then just add the value of "name" to the resulting array. Example (assuming the dictionary is named d):
NSDictionary* d = ...
NSMutableArray* array = [NSMutableArray arrayWithCapacity:d.count];
for(NSDictionary* member in d.objectEnumerator) {
[array addObject:[member objectForKey:#"name"]];
}
Krumelur was faster than me ;) He is right by saing that you should traverse the dictionary values first. In your implementation you don't reference your counter variable i somewhere, so the NSString name is the same in each iteration.
This may help you..
// here you can get Array of Dictionary First
NSArray *arr = [[NSArray alloc] initWithContentsOfFile:#""]; // get array first from your response
NSDictionary *temp = [[NSDictionary alloc] initWithDictionary:self.currentChannel.members];
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSDictionary *temp = [arr objectAtIndex:i];
NSString *name=[NSString stringWithFormat:#"%#",[temp objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
Thanks.

How to get object index?

How can I get my object index? I have a dictionary containing arrays and inside the arrays i have multiple dictionary.
My data structure(eg):
Student ------ NSDictionary
Item 0 ------ NSArray<br>
Name ----- Grace<br>
Age ----- 20<br>
Item 1 ------ NSArray<br>
Name ----- Anne<br>
Age ----- 21<br>
So for example, I have the value of the name, Grace, and I want to get the value of the object index array (in this case, item 0). How can I do so?
I've used the indexOfObject however the results I got back is 2147483647, which i think it means nsnotfound. So i think it doesnt work for this case.
This are my codes:
NSMutableDictionary* namevalue = [[NSMutableDictionary alloc] init];
namevalue = [somedict objectForKey:#"Name"];
int arryindex;
arryindex = [somearray indexOfObject:namevalue];
NSLog(#"Array Index:%i", arryindex);
Can anyone help? Thank you so much!
In your code you forgot to include the creation of somedict and somearray. The problem may be there.
Also, you don't need to assign namevalue an empty dictionary and then the actual dictionary inside the array.
Check this fragment of working code:
NSUInteger idx;
NSDictionary *john = [NSDictionary dictionaryWithObjectsAndKeys:#"John", #"name",
[NSNumber numberWithInt:23], #"age", nil];
NSDictionary *jane = [NSDictionary dictionaryWithObjectsAndKeys:#"Jane", #"name",
[NSNumber numberWithInt:24], #"age", nil];
NSArray *students = [NSArray arrayWithObjects:john, jane, nil];
idx = [students indexOfObject:john];
NSLog(#"john is at: %i", idx == NSNotFound ? -1 : idx); /* 0 */
idx = [students indexOfObject:jane];
NSLog(#"jane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */
Now, try with an object not present in the array:
NSDictionary *mary = [NSDictionary dictionaryWithObjectsAndKeys:#"Mary", #"name",
[NSNumber numberWithInt:22], #"age", nil];
idx = [students indexOfObject:mary];
NSLog(#"mary is at: %i", idx == NSNotFound ? -1 : idx); /* -1 Not found */
And finally with a new object but created as an exact duplicate of an object already present in the array:
NSDictionary *maryjane = [NSDictionary dictionaryWithObjectsAndKeys:#"Jane", #"name",
[NSNumber numberWithInt:24], #"age", nil];
idx = [students indexOfObject:maryjane];
NSLog(#"maryjane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */
The method indexOfObject will use isEqual: to compare objects. You can verify that the new object will be considered as equal to the one inside the array:
NSLog(#"jane is maryjane? %i", [jane isEqual:maryjane]); /* 1 */
If I understood correctly, you're looking for a way to find object index in NSDictionary based on the value of property that object has, right?
E.g. your students dictionary has a student with name Grace and you would like to know at which index the student object with name Grace is stored...
If above is true, here's my (incomplete and rough) solution which works only for objects with NSString properties, but once you get the idea below, I think you'll be able to modify code to match your needs.
- (NSInteger)indexOfObjectWithPropertyValue:(id)value inDictionary:(NSDictionary *)dict {
NSInteger objectIndex = 0;
unsigned int outCount, i;
for (id key in dict) {
id objForKey = [dict objectForKey:key];
Class lender = [objForKey class];
objc_property_t *properties = class_copyPropertyList(lender, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
id v = [objForKey valueForKey:[NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]];
if ([v isKindOfClass:[value class]] && [v isEqual:value]) {
return objectIndex;
}
}
objectIndex++;
}
return NSNotFound; // i.e. NSIntegerMax
}
and don't forget to include runtime header:
#import <objc/runtime.h>
My code may and probably have some issues:
the most obvious isEqual: method which needs to compare properties' values.
above code does not cover a situation when there are many objects with same value (like many students with the same name!)
???
I hope my "answer" will make it easier for you to implement what you need.

Sort an array with numeric strings

Hello I have an array of persons, and i am trying to sort them by age using a sort descriptor.
The age field in a patient is a string so when calling:
ageSorter = [[NSSortDescriptor alloc] initWithKey:#"age" ascending:YES];
[personList sortUsingDescriptors:[NSArray arrayWithObject:ageSorter]];
It sorts them but 100 appears first because its is not using numericSearch in the compare options.
Is there a ways i can still sort with descriptor but maybe using a selector to change how to compare the strings?
The finderSortWithLocale method (both these are taken from apple api):
int finderSortWithLocale(Person *person1, Person *person2, void *locale)
{
static NSStringCompareOptions comparisonOptions = NSNumericSearch;
NSRange string1Range = NSMakeRange(0, [string1 length]);
NSString *age1 = person1.age;
NSString *age2 = person2.age;
return [age1 compare:age2
options:comparisonOptions
range:string1Range
locale:(NSLocale *)locale];
}
How to call this method (edited: call the function on array of Persons):
NSArray *sortedArray = [personList sortedArrayUsingFunction:finderSortWithLocale
context:[NSLocale currentLocale]];
I also faced the same issue and found answer here.
Instead of NSString comparison, do with your object property. i.e for age.
Example. : In ascending order :
NSArray *sortedArray = [_arrayCaptureLeadList sortedArrayUsingComparator:^(Person *obj1, Person *obj2) {
return [obj1.age compare:obj2.age options:NSNumericSearch];
}];
NSMutableArray *filterResultArray = [NSMutableArray arrayWithArray:sortedArray];
In descending order :
NSArray *sortedArray = [_arrayCaptureLeadList sortedArrayUsingComparator:^(Person *obj1, Person *obj2) {
return [obj2.age compare:obj1.age options:NSNumericSearch];
}];
NSMutableArray *filterResultArray = [NSMutableArray arrayWithArray:sortedArray];
I know this is very late to reply your question but may this will be helpful for others. ^_^
You could create a category on NSString that adds a method numericCompare: and which calls [self compare:otherString options:NSNumericSearch]. Another option is to convert the age field into a NSNumber instead of a NSString. Yet another option involves a NSComparator block and sortUsingComparator.