Extract objects with specific date from custom object Array - ios

I have an ordered array of Availability object which is a class containing two attributes, startAt and endAt.
I'd like to extract from my availability array the objects from a specific day without taking into account the time.
I'd also like to use NSPredicate instead of "for" loop to do it.
Could you help me?
Thanks

for-in loop actually faster than NSPredicate for me, and easier since u can convert it to string or extract it for easy compare, but if u want then the format should be:
#"(%# >= %#) AND (%# <= %#)", dateForCompare, dayStart, dateForCompare, dayEnd where dayStart is the date to compare at 00:00:00, dayEnd is the date to compare at 23:59:59, tweak it base on your needs, u have to do this because a NSDate object contain exact date and time
Hope it help

if you are using timestamp(NSNumber) to store startAt and endAt then you can use predicate as bellow (to fetch all object whose start date is greter then current date)
NSPredicate *pred = [NSPredicate predicateWithFormat:#"startAt > %#", [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]];
NSArray *filteredArr = [yourArray filteredArrayUsingPredicate:pred];
and if you are using only date string then you can use
NSPredicate *pred = [NSPredicate predicateWithFormat:#"startAt = %#", #"your date string must be same as formate you saved in array"];
and if you are using only date string then you can use

Related

How to set predicate for a string attribute holding integer value in core data

How to set predicate for a string attribute holding integer value in core data to get the in-between values in integer.
I am using compound predicate for multiple conditions and a piece of code follows..
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"rating >= %# AND rating <= %#",ratingFrom.text,ratingTo.text];
[compoundPredicateArray addObject: categoryPredicate ];
"rating" attribute is of type string in database. I need to get the rating between the given range in the ratingFrom & ratingTo textfields.
"1" to "10" should fetch all ratings in between 1 to 10.how can I achieve this, without changing the attribute type to number.
Any help appreciated..Thanks
i am not confirm but try this
convert your values in NSString and put this code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"string CONTAINS[c] %#",searchText];
Ideally you should change this attribute to be a number rather than a string. But if that's not possible, the following should force CoreData (or rather SQLite) to treat it as a number:
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"add:to:(rating,0) >= %d AND add:to:(rating,0) <= %d",ratingFrom.text.intValue,ratingTo.text.intValue];
you can try BETWEEN expression:
BETWEEN The left-hand expression is between, or equal to either of,
the values specified in the right-hand side. The right-hand side is a
two value array (an array is required to specify order) giving upper
and lower bounds. For example, 1 BETWEEN { 0 , 33 }, or $INPUT BETWEEN
{ $LOWER, $UPPER }. In Objective-C, you could create a BETWEEN
predicate as shown in the following example:
So your code should look like this:
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: #"rating BETWEEN %#", #[ratingFrom, ratingTo]];
ratingFrom, ratingTo should be NSNumber instances if rating is NSNumber.

add componentsseparatedbystring into a predicate with core data

i have a String stored in an Entity (core data) i want to use an NSFetchedResultsController to get data.
string format: abc,ba,x,s,d. this is an array of IDs saved as string.
i want to get only entities that contains at least an IDs in that string.
the problem is if i use CONTAIN in the predicate and search for "a" i will get a wrong result.
could you please tel me if it's possible to add something like "componentsseparatedbystring" in a predicate so i can iterate and use "in"in the result or if there's an other solution, thanks.
You can use the "MATCHES" operator in a predicate, which does a
regular expression match:
NSString *searchID = #"a";
NSString *pattern = [NSString stringWithFormat:#"(^|.*,)%#(,.*|$)",
[NSRegularExpression escapedPatternForString:searchID]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID MATCHES %#", pattern];
The pattern (^|.*,)TERM(,.*|$) searches for TERM which is preceded
by either the start of the string or a comma, and followed by the
end of the string or another comma.
First convert your array of ID's into an NSArray:
NSArray *arrayOfIds = [stringOfIds componentsSeparatedByString:#","];
Then use an IN predicate on your fetch:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID IN %#", arrayOfIds];
this assumes your database column is called "ID", and your comma-separated string of ID's is stringOfIds.
finally i will use a dirty solution: we have 4 possibilities:
string format= a
string format= a,..
string format= ..,a
string format= ..,a,..
so the predicate could be:
[NSPredicate predicateWithFormat:#"(ID LIKE %# OR
ID CONTAINS %# OR
ID CONTAINS %# OR
ID ENDSWITH %#)",
searchedID,
[NSString stringWithFormat:#"%#,", searchedID],
[NSString stringWithFormat:#",%#", searchedID],
[NSString stringWithFormat:#",%#,", searchedID]]
but this is a dirty solution, i really want something cleaner.

issue in NSPredicate for NSString

In my application I am using CoreData.Amount values are stored in coreData as NSString. In my Interface Builder i have two textfields.When i enter any amount on my textfields This amounts will accept as Minimum Value and maximum Value.I want to get all amounts between minimum and maximum amounts i have entered.
What will be the solution.I just goes through this way Example It Not be worked on my project because i want to convert string to integer on my NSPredicate method.
My code is
NSPredicate *p1= [NSPredicate predicateWithFormat:#"(amount.intValue => %#) && (amount.intValue <=%#)", text1.intValue,text2.intValue]];
Note that amount is stored as NSString in coredata
NSPredicate *p1= [NSPredicate predicateWithFormat:#"(amount.intValue => %#) && (amount.intValue <=%#)", text1.intValue,text2.intValue]];
You shouldn't be comparing numbers and strings. Compare one or the other. In this case, you want to compare numbers. You should change your source data stored in the model to be a number.
=> should be >=
%d is an integer parameter format, and text1.intValue returns an integer. Using %# expects an on jest and won't do what you want.
Log the contents of the predicate so you can see what it contains. But mainly, change the type of the data in the model.
As you store amount as NSString, you need to pass it as NSNumber when doing the evaluation.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.intValue <= $max.intValue AND SELF.intValue >= $min.intValue"];
Now you can evaluate the amount to see if it is in range
if ([predicate evaluateWithObject:[NSNumber numberWithInt:amount.intValue] substitutionVariables:#{#"max":[NSNumber numberWithInt:text1.intValue], #"min":[NSNumber numberWithInt:text2.intValue]}])
{
//Got the correct amount
}
Currect Answer is
NSPredicate *p1= [NSPredicate predicateWithFormat:#"(amount >= %d) && (amount <= %d)", text1.intValue, text2.intValue]];

NSPredicate issue with greater than equals

I have a simple NSPredicate which is not giving correct result
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF.data.squareFootage >= %#", filterSquareFootage];
filteredArray = [[filteredArray filteredArrayUsingPredicate:resultPredicate] mutableCopy];
Strangely this works for all 6000>=250, 7000>=250, 8000>=6000. But as soon as squareFootage==10000 the predicate for 10000>=any smaller value is false.
Note: 10000 for squareFootage is a max value fetched using a UISlider.If i reduce value to any smaller value, the predicate gives true as result
Am i missing something here and using predicate incorrectly?
I assume that your property is stored as string and not as number, therefore
the values are compared as strings:
"10000" < "250" < "6000"
Using NSNumber instead of NSString (or alternatively some scalar type as NSInteger) should fix the problem.
If you cannot change the data type of the squareFootage property, then the following
predicate should work:
[NSPredicate predicateWithFormat:#"SELF.data.squareFootage.intValue >= %d", [filterSquareFootage intValue]]
YOU CAN"T COMPARE STRINGS USING =< . if SELF.data.squareFootage is a NSNumber try converting filterSquareFootage to NSnumber or int value and compare them like that.

NSPredicate crash on CONTAINS?

I'm trying to do a simple predicate filter on an array of objects.
The objects in the array have 2 properties, displayValue and value. I am trying to filter based on a search string and I get a crash.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"displayValue CONTAINS[cd] %#", searchString];
NSArray *results = [_data filteredArrayUsingPredicate:pred];
what exactly is incorrect about this format that it causes a Can't use in/contains operator with collection 100 (not a collection) crash?
I was able to reproduce your problem. This happens if the displayValue of one of the objects
is not a NSString, but some different type.
From your error message, I assume that you assigned an NSNumber, for example
obj.displayValue = #100;
somewhere in your code. The "CONTAINS" predicate works only with strings, so you must assign
only string values to the property.
Therefore, you should define the type of the property as
NSString * instead of id, and check the assignments to that property.
If you really need to keep the id type and store different kinds of objects in that property,
then you cannot use the "CONTAINS" operator in the predicate. A direct comparison
with #"displayValue == %#" would work, however.
UPDATE: As a workaround, you could use the description method, which converts any object
to a string, in particular it converts a NSNumber to its string representation. So the following could work:
[NSPredicate predicateWithFormat:#"displayValue.description CONTAINS[cd] %#", searchString];
The drawback is that the exact description format is not documented.
Another solution could be to use a block-based predicate, where you can check the type
of each object and perform the appropriate comparison.

Resources