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.
Related
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);
I have an NSMutableArray of dictionaries. I am using NSPredicate to filter through the array to find if a dictionary with a particular key exists or not.
I have referred to various examples, one of the closest is here: Using NSPredicate to filter an NSArray based on NSDictionary keys. However, I don't wish to have a value to the key. My problem is that I want to find the key first. I tried different syntaxes, but it did not help.
What I have done so far:
NSString *key = #"open_house_updated_endhour";
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K", key];
//NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K contains [cd]", key]; Doesn't work.
//NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K == %#", key]; Won't work because it expects a value here.
NSLog(#"predicate %#",predicateString);
NSArray *filtered = [updatedDateAndTime filteredArrayUsingPredicate:predicate]; // updatedDateAndTime is the NSMutableArray
A dictionary delivers nil as value for absent key. So simply compare the key against nil.
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K==NULL", key]; // Dictionaries not having the key
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K!=NULL", key]; // Dictionaries having the key
Try it:
NSArray *Myarray = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:#"my hello string" forKey:#"name"]];
NSArray *filteredarray = [Myarray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(name == %#)", #"my hello string"]];
NSLog("%#",filteredarray);
Another example :
NSString *mycategory = #"iamsomeone";
NSArray *myitems = #[#{ #"types" : #[#"novel", #"iamsomeone", #"dog"] },
#{ #"types" : #[#"cow", #"iamsomeone-iam", #"dog"] },
#{ #"types" : #[#"cow", #"bow", #"cat"] }];
NSPredicate *mypredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSArray *categories = [evaluatedObject objectForKey:#"types"];
return [categories containsObject:mycategory];
}];
NSArray *outpuArray = [myitems filteredArrayUsingPredicate:mypredicate];
NSLog(#"hello output:%#",outpuArray);
I have a NSArray of NSDictionary.
One of the keys of the NSDictionary contains a NSArray of strings.
Is there a way that I can use NSPredicate to find a specific strins in that Array of strings?
Thanks :)
Also: This work great, but not for sublevelArray
predicate = [NSPredicate predicateWithFormat:#" %K LIKE[cd] %#", sKey, sLookForString];
Just replace LIKE with CONTAINS in your format string. For example, given this array:
NSArray *dogs = #[#{#"name" : #"Fido",
#"toys" : #[#"Ball", #"Kong"]},
#{#"name" : #"Rover",
#"toys" : #[#"Ball", #"Rope"]},
#{#"name" : #"Spot",
#"toys" : #[#"Rope", #"Kong"]}];
...the following predicate can be used obtain a filtered array containing only the dictionaries where the value for the key toy is an array that contains the string Kong.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", #"toys", #"Kong"];
On NSArray you can use filteredArrayUsingPredicate:, on NSDictionary use enumerateKeysAndObjectsUsingBlock: and then for each value do either a filteredArrayUsingPredicate: if it is an NSArray or you can use evaluateWithObject: using the predicate itself.
If you want to filter the array of dictionaries based on the array of strings, you can use -predicateWithBlock to filter the array, as shown in the code below:
- (NSArray *)filterArray:(NSArray *)array WithSearchString:(NSString *)searchString {
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *dictionary = (NSDictionary *)evaluatedObject;
NSArray *strings = [dictionary objectForKey:#"strings"];
return [strings containsObject:searchString];
}];
return [array filteredArrayUsingPredicate:predicate];
}
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.
I have an NSMutableDictionary with integer values, and I'd like to get an array of the keys, sorted ascending by their respective values. For example, with this dictionary:
mutableDict = {
"A" = 2,
"B" = 4,
"C" = 3,
"D" = 1,
}
I'd like to end up with the array ["D", "A", "C", "B"]. My real dictionary is much larger than just four items, of course.
The NSDictionary Method keysSortedByValueUsingComparator: should do the trick.
You just need a method returning an NSComparisonResult that compares the object's values.
Your Dictionary is
NSMutableDictionary * myDict;
And your Array is
NSArray *myArray;
myArray = [myDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
Just use NSNumber objects instead of numeric constants.
BTW, this is taken from:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Dictionaries.html
NSDictionary has this neat method called allKeys.
If you want the array to be sorted though, keysSortedByValueUsingComparator: should do the trick.
Richard's solution also works but makes some extra calls you don't necessarily need:
// Assuming myDictionary was previously populated with NSNumber values.
NSArray *orderedKeys = [myDictionary keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [obj1 compare:obj2];
}];
Here's a solution:
NSDictionary *dictionary; // initialize dictionary
NSArray *sorted = [[dictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[dictionary objectForKey:obj1] compare:[dictionary objectForKey:obj2]];
}];
The simplest solution:
[dictionary keysSortedByValueUsingSelector:#selector(compare:)]
Here i have done something like this:
NSMutableArray * weekDays = [[NSMutableArray alloc] initWithObjects:#"Sunday",#"Monday",#"Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday", nil];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *dictArray = [[NSMutableArray alloc] init];
for(int i = 0; i < [weekDays count]; i++)
{
dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:i],#"WeekDay",[weekDays objectAtIndex:i],#"Name",nil];
[dictArray addObject:dict];
}
NSLog(#"Before Sorting : %#",dictArray);
#try
{
//for using NSSortDescriptor
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"WeekDay" ascending:YES];
NSArray *descriptor = #[sortDescriptor];
NSArray *sortedArray = [dictArray sortedArrayUsingDescriptors:descriptor];
NSLog(#"After Sorting : %#",sortedArray);
//for using predicate
//here i want to sort the value against weekday but only for WeekDay<=5
int count=5;
NSPredicate *Predicate = [NSPredicate predicateWithFormat:#"WeekDay <=%d",count];
NSArray *results = [dictArray filteredArrayUsingPredicate:Predicate];
NSLog(#"After Sorting using predicate : %#",results);
}
#catch (NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorting cant be done because of some error" message:[NSString stringWithFormat:#"%#",exception] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert setTag:500];
[alert show];
[alert release];
}