NSArray empty with filteredArrayUsingPredicate ios - iphone

i have a little problem with "predicate"
i have NSArray (datesArray) which is composed to :
(
"2011-11-30",
"2011-11-28",
"2011-11-25"
)
and another NSArray (leadsArray) which composed to :
(
{
"date_deadline" = "2011-11-30";
name = "test1";
};
{
"date_deadline" = "2011-11-28";
name = "test2";
};
{
"date_deadline" = "2011-11-25";
name = "test3";
};
{
"date_deadline" = "2011-11-28";
name = "test4";
};
)
then i do that :
NSString *date = [datesArray objectAtIndex:section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date beginswith %#", date];
NSArray *leads = [leadsArray filteredArrayUsingPredicate:predicate];
return [leads count];
But my NSAraay (leads) is empty.
I do that to know the "numberOfRowsInSection".
Can you help me please?

As the key for the dates in your dictionary is "date_deadline" it should at least read
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date_deadline beginswith %#", date];
In any case consider if you needs beginswith or can test for equal and if you need to store strings for dates or can use NSDate objects.

Related

Objective C: Filter out results from NSMutableArray by a dictionary key's value?

I have a NSMutableArray like this :
(
{
City = "Orlando";
Name = "Shoreline Dental";
State = Florida;
},
{
City = "Alabaster ";
Name = Oxford Multispeciality;
State = Alabama;
},
{
City = Dallas;
Name = "Williams Spa";
State = Texas;
},
{
City = "Orlando ";
Name = "Roast Street";
State = Florida;
}
)
Now how can I sort this NSMutableArray to get the results corresponding to State "Florida"
I expect to get
(
{
City = "Orlando";
Name = "Shoreline Dental";
State = Florida;
},
{
City = "Orlando ";
Name = "Roast Street";
State = Florida;
}
)
I went for this code,but it displays again the prevous four dictionaries .
NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Florida" ascending:YES];
NSArray * descriptors = [NSArray arrayWithObject:valueDescriptor];
NSArray * sortedArray = [arr sortedArrayUsingDescriptors:descriptors];
Try using a comparator block:
NSIndexSet *indices = [array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[obj objectForKey:#"State"] isEqualToString:#"Florida"];
}];
NSArray *filtered = [array objectsAtIndexes:indices];
Alternatively, you can use a predicate as well:
NSPredicate *p = [NSPredicate predicateWithFormat:#"State = %#", #"Florida"];
NSArray *filtered = [array filteredArrayUsingPredicate:p];
If your array contains dictionary then you can use NSPredicate to filter out your array as follows:
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:#"State CONTAINS[cd] Florida"];
theFilteredArray = [theArray filteredArrayUsingPredicate:thePredicate];
Assuming your array name is : arr
This one of the typical way to find, although a bit obsolete way....
for (NSDictionary *dict in arr) {
if ([[dict objectForKey:#"State"]isEqualToString:#"Florida"]) {
[filteredArray addObject:dict];
}
}
NSLog(#"filteredArray->%#",filteredArray);
Using predicates and blocks are already posted :)
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"State = %#", #"Florida"];
NSArray *filteredArray = [arr filteredArrayUsingPredicate:predicate];
NSLog(#"filtered ->%#",filteredArray);

NSPredicate doesn't filter data for long value in iOS 5

I am trying to filter data from array using NSPredicate.
My array (arrLikes) contains following data from server
{
"id":17,
"likes":[
{
"likedBy":
{
"firstName":"Bob",
"lastName":"Builder",
"id":1
}
}],
"comments":[]
}
I am trying to filter the data from array like below
long loggedInUserId = [[dictUserInfo objectForKey:#"id"] longValue];
NSPredicate *likePredicate = [NSPredicate predicateWithFormat:#"id == %ld", loggedInUserId ];
NSArray *filteredLikeArray = [arrLikes filteredArrayUsingPredicate:likePredicate];
Even if my loggedInUserId is 1 , filteredLikeArray count retruns 0.
What wrong in above code ?
Any kind of help is appreciated. Thanks.
Did you try converting long into NSString as follows?
long loggedInUserId = 17;
NSString *stringUserId = [NSString stringWithFormat:#"%ld", loggedInUserId];
NSPredicate *likePredicate = [NSPredicate predicateWithFormat:#"id == %#", stringUserId];
NSArray *filteredLikeArray = [arrLikes filteredArrayUsingPredicate:likePredicate];

Filtering NSArray/NSDictionary using NSPredicate

I've been trying to filter this array (which is full of NSDictionaries) using NSPredicate...
I have a very small amount of code that just isn't working...
The following code should change label.text to AmyBurnett34, but it doesn't...
NSPredicate *pred = [NSPredicate predicateWithFormat:#"id = %#", [[mightyPlistDict objectForKey:#"pushesArr"] objectAtIndex:indexPath.row]];
NSLog(#"%#",pred);
label.text = [[[twitterInfo filteredArrayUsingPredicate:pred] lastObject] objectForKey:#"screen_name"];
NSLog(#"%#",twitterInfo);
And here is what gets NSLoged...
2012-08-05 11:39:45.929 VideoPush[1711:707] id == "101323790"
2012-08-05 11:39:45.931 VideoPush[1711:707] (
{
id = 101323790;
"screen_name" = AmyBurnett34;
},
{
id = 25073877;
"screen_name" = realDonaldTrump;
},
{
id = 159462573;
"screen_name" = ecomagination;
},
{
id = 285234969;
"screen_name" = "UCB_Properties";
},
{
id = 14315150;
"screen_name" = MichaelHyatt;
}
)
Just for the heads up if you also NSLog this... the array is empty...
NSLog(%#,[twitterInfo filteredArrayUsingPredicate:pred]);
The problem is that your predicate is using comparing with a string and your content is using a number. Try this:
NSNumber *idNumber = [NSNumber numberWithLongLong:[[[mightyPlistDict objectForKey:#"pushesArr"] objectAtIndex:indexPath.row] longLongValue]];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"id = %#", idNumber];
You don't know for sure that the value of "id" is a string - it might be a NSNumber. I suggest:
NSUInteger matchIdx = ...;
NSUInteger idx = [array indexOfObjectPassingTest:^BOOL(NSDictionary *dict, NSUInteger idx, BOOL *stop)
{
id obj = [dict objectForKey:#"id"];
// NSLog the class if curious using NSStringFromClass[obj class];
NSUInteger testIdx = [obj integerValue]; // works on strings and numbers
return testIdx == matchIdx;
}
if(idx == NSNotFound) // handle error
NSString *screenName = [[array objectAtIndex:idx] objectForKey:#"screen_name"];
NSPredicate is used for filtering arrays, not sorting them.
To sort an array, use the sortedArrayUsingDescriptors method of NSArray.
An an example:
// Define a sort descriptor based on last name.
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"lastName" ascending:YES];
// Sort our array with the descriptor.
NSArray *sortedArray = [originalArray sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor, nil]];

How do I create the right NSPredicate for this kind of request?

Hi the problem goes like this:
I have in CoreData entities that have a title and a relationship to keywords entities.
I need a predicate that helps me to fetch all those entities whose title contains the keywords I type. I have the code below that should do this but it doesn't:
NSArray *keywords = [searchString componentsSeparatedByString:#" "];
NSString *predicateString = #"";
for(NSInteger i = 0; i < [keywords count]; i++) {
if(((NSString*)[keywords objectAtIndex:i]).length != 0) {
if(i==0) {
predicateString = [keywords objectAtIndex:i];
}
else {
predicateString = [predicateString stringByAppendingFormat:#" and keywords.normalizedKeyword contains[cd] %#", [keywords objectAtIndex:i]];
}
}
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keywords.normalizedKeyword contains[cd] %#",predicateString];
For example I have entities with titles like this:
1) "Great Coloring theme"
2) "Theme for kids"
3) "Cars for kids"
my keywords db will contain:
great
coloring
theme
for
kids
cars
How can I create a predicate so when I type for example:
Theme for
the result will be 2) and 3)
or if I type:
great theme
the result will be 1) and 2)
Any help in getting the right predicate to achieve this is very much appreciated. What I tried to do there it doesn't work and I am out of ideas.
Thanks!
I have found the answer myself. To solve such a problem you have to use a NSCompoundPredicate.
The solution to my problem was this:
NSArray *keywords = [lowerBound componentsSeparatedByString:#" "];
NSMutableArray *predicates = nil;
for(NSInteger i = 0; i < [keywords count]; i++) {
if(((NSString*)[keywords objectAtIndex:i]).length != 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keywords.normalizedKeyword contains[cd] %#", [keywords objectAtIndex:i]];
if(predicates == nil) {
predicates = [[NSMutableArray alloc] initWithCapacity:0];
}
[predicates addObject:predicate];
}
}
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];

NSCompoundPredicate fails to match

I'm building a NSPredicate using the code below for an iPhone app. The logging shows the prediate to be: location CONTAINS "head" AND shape CONTAINS "oval" AND texture CONTAINS "bumpy" AND colour CONTAINS "red"
I get no results. If I limit the predicate to a single item it will work, more than 1 fails.
Can anyone tell me why?
Many thanks
NSMutableArray *subPredicates = [[NSMutableArray alloc] init];
for (Ditem in self.tableDataSource) {
NSString *Title = [Ditem valueForKey:#"Title"];
NSString *Value = [Ditem valueForKey:#"Value"];
if([[Value lowercaseString] isEqualToString: #"all"]){
Value = #"";
}
else{
NSPredicate *p = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:[Title lowercaseString]] rightExpression:[NSExpression expressionForConstantValue:[Value lowercaseString]] modifier:NSDirectPredicateModifier type:NSContainsPredicateOperatorType options:0];
[subPredicates addObject:p];
}
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
NSLog(#"predicate: %#", predicate);[self.fetchedResultsController.fetchRequest setPredicate:predicate];
Your predicate is requiring that all of the values in your filterable objects be strings. Is that correct?
Also, I would simplify your subpredicate creation to:
NSPredicate * p = [NSPredicate predicateWithFormat:#"%K CONTAINS %#", [Title lowercaseString], [Value lowercaseString]];