I have a core data attribute titled 'gLotNumber' which stores alphanumeric strings. Examples include P1, P5, 7, P10 and 11.
I need to provide a way to search this attribute to the user. The way I can think of providing this is by using NSPredicate on core data using:
[fetchRequest1 setPredicate:[NSPredicate predicateWithFormat:#"(gLotNumber >= 'P1') AND (gLotNumber <= 'P15')"]];
This should result in all entries which start with P and range between 1 to 15. The above code doesn't produce accurate results at all.
Do you know how this can be achieved?
I believe this should work
I don't have a coredata setup hence harcoded some array values.
NSArray *array = #[#{#"gLotNumber":#"P1"},#{#"gLotNumber":#"P15"},#{#"gLotNumber":#"P13"},#{#"gLotNumber":#"P0"},#{#"gLotNumber":#"11"},#{#"gLotNumber":#"10"},#{#"gLotNumber":#"P31"},#{#"gLotNumber":#"P013"},#{#"gLotNumber":#"16"},#{#"gLotNumber":#"P38"}];
NSArray *filtered = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF.gLotNumber BEGINSWITH 'P' AND SELF.gLotNumber <= 'P15'"]];
NSSortDescriptor *desc = [NSSortDescriptor sortDescriptorWithKey:#"gLotNumber" ascending:YES comparator:^NSComparisonResult(id obj1,id obj2){
return [obj1 compare:obj2 options:NSNumericSearch];
}];
NSArray *sorted = [filtered sortedArrayUsingDescriptors:#[desc]];
You can set the sort descriptor and predicate to the fetch request Hope this helps
Related
I have a Core Data object Contact
Contact
=======
fullName
I'm using a NSFetchedResultsController to show a list of contacts.
I now want to add search option that behave as follow:
If user search for the string "da", the results should be:
Aaron David
Bert Daniels
Dana
John David
So the search result is alphabetic sorted strings that has a word starting with "da"
I remember watching a WWDC session showing how to create a Word object and store each word independently, but I'm trying to avoid this approach.
So my question is, can I do such a search with my current model structure and some predicate magic, or I must store the fullName as separate words?
This is what I do:
NSMutableArray *predicateArray = [NSMutableArray array];
if(searchString.length)
{
for (NSString* searchStringPart in [searchString componentsSeparatedByString:#" "])
{
if([searchStringPart length] > 0)
{
[predicateArray addObject:[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", searchStringPart]];
}
}
filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[filterPredicate, [NSCompoundPredicate andPredicateWithSubpredicates:predicateArray]]];
}
And for sorting:
NSSortDescriptor *sort = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
NSArray* sortDescriptors = #[sort];
....
[fetchRequest setSortDescriptors:sortDescriptors];
You need to use predicate for filtered word by name in your array. Use below:-
//Assuming you have store the name in one array
NSArray *names=#[#"Aaron David",#"Bert Daniels",#"Dana",#"John David"];
//Now use contains in predicate for filtered words
//On the basis of search string it will filtered accordingly. lets Say yourStringValue=#"on"
NSPredicate *pd=[NSPredicate predicateWithFormat:#"self CONTAINS[CD] %#",yourStringValue];
NSArray *ar=[names filteredArrayUsingPredicate:pd];
NSLog(#"%#",ar);
Output:-
"Aaron David"
I have a list of managed objects stored in core data. I use these objects to populate a tableview controller that is sectioned according to alphabetical order. The data in these objects is obtained via web service, so I have no control over their case (which really doesn't make much difference in this case).
Most of the data is returned in all caps. I've noticed that, on the rare occasions where the case is NOT all caps, those items do not fall into alphabetic order. In the following code sample, stationIndex is an array of sorted first letters:
for(NSString *character in stationIndex){
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name beginswith[c] %#", character];
// sort the list
NSArray *filteredGaugeList = [[tempGaugeList filteredArrayUsingPredicate:pred] sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [(Gauge*)a name];
NSString *second = [(Gauge*)b name];
return [first compare:second];
}];
if([filteredGaugeList count] > 0){
[[self allGauges] addObject:filteredGaugeList];
}
}
I'm aware that there is a way to ignore case when using a selector, but in my case, I'm sorting on properties of objects, so I'm assuming I need a comparator. Is there a way to handles case in this situation? Thanks!
You can sort ignoring case in a comparator as well, just use
return [first caseInsensitiveCompare:second];
Alternatively, use a sort descriptor specifying the selector and the sort key:
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(caseInsensitiveCompare:)];
NSArray *sorted = [array sortedArrayUsingDescriptors:#[sort]];
Remark: To display Core Data objects in a table view, you can also use
NSFetchedResultsController. Then you would add the predicate and the sort
descriptor to the fetch request. A fetched results controller has also methods
to group a table view into sections, and to update a table view automatically
when objects are inserted/deleted/modified.
I am new to ios.
I have a NSMutableArray of NSDictionary. How can I filter the array?
//sections is a NSMutableArray of NSMutableDictionary elements
[sections addObject:getName];
NSSortDescriptor *sortDescriptorFirst = [NSSortDescriptor sortDescriptorWithKey:#"first" ascending:YES];
NSSortDescriptor *sortDescriptorLast = [NSSortDescriptor sortDescriptorWithKey:#"last" ascending:YES];
NSSortDescriptor *descriptor=[NSArray arrayWithObjects:sortDescriptorFirst,sortDescriptorLast,nil];
NSArray *sortedArray =[sections sortedArrayUsingDescriptors:descriptor];
How to continue the code from here in order to match the array with the regex value?
If I understand your question correctly, you need a string that contains all
values of a dictionary. That would be:
NSString *str = [[dict allValues] componentsJoinedByString:#" "];
and then you can check if str matches the given regex pattern as before.
Ok from the look of your post it looks like you can just use an NSPredicate instead of a RegEx
try something along the lines of this:
NSPredicate* p = [NSPredicate predicateWithFormat:#"key = %#", value];
NSArray* matches = [arrayOfDicts filteredArrayUsingPredicate:p];
NSPredicate can use all sorts of operators such as LIKE, !=, and <
if you need to filter based on a value being in a list you can construct a predicate along the lines of #"key IN %#", arrayOfPossibleValues
replace key in that sample code with the key in the dictionary you are trying to filter by. you can filter using multiple keys if needed.
I have values from 200 to 1 stored as strings in an array called beaus.
NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:#"dataoflar" ascending:NO];
[beaus sortUsingDescriptors:#[sortDesc]];
However, this only sorts them by the first number (2 is above 10). Is there any way to sort by amount?
You can update your sort description like this:
NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:#"dataoflar.integerValue" ascending:NO];
[beaus sortUsingDescriptors:#[sortDesc]];
This will get the integer value of each string and the sort will be based on that number instead of the string value.
Assuming it doesn't matter that the values are NSStrings in the final array you should sort it like this
NSMutableArray *mutableBeaus = [[beaus mutableCopy] autorelease];
[mutableBeaus sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
// mutableBeaus now has the array sorted in an ascending order 1 < 002 < 3
If for some reasons you don't want to convert the Strings to int during import, you
have to write and use your own Sorter:
This shows how to sort beause by property "datatoflat" of type NSString which contain number. Sort is done ascending. For descending exchange the last line to return (i1- i2).
NSArray *sortedArray;
sortedArray = [beaus sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString* s1 = [(NSString*) a dataoflar];
NSString* s2 = [(NSString*) b dataoflar];
int i1 = [s1 integerValue];
int i2 = [s2 integerValue];
return (i2 - i1);
}];
If you have to use strings, then left fill you numbers with zeros, then it will sort like you want with not other changes, like this:
'002' instead of '2' and '034' instead of '34'
I'm doing some small work on sorting the date strings in the NSMutableArray, i'm getting the array from the sqlite db.
If you print the array it is showing like this
date strings are (
"2011-05-01",
"2011-02-01",
"2012-01-08",
"2012-05-08",
"2010-01-09
)
I want to show the dates in ascending order. Please help me out guys..... I'm newbie to objc..
First you should convert all date Strings (which is NSString) objects to NSDate objects and then sort these dateObjects.
I believe you have dateArray containing all those strings.
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self"
ascending:NO];
NSArray *descriptors = [NSArray arrayWithObject:descriptor];
NSArray *reverseOrder = [dateArray sortedArrayUsingDescriptors:descriptors];
OR
NSArray *reverseOrderUsingComparator = [dateArray sortedArrayUsingComparator:
^(id obj1, id obj2) {
return [obj2 compare:obj1];
}];
If your dates are really strings in the format YYYY-mm-dd, as in your question, then this will sort them in ascending order:
[arrayOfDates sortUsingSelector:#selector(compare:)];
That will also work if your dates are actually NSDate objects.
If you want to create a sorted copy of the array:
NSArray *sortedArray = [arrayOfDates sortedArrayUsingSelector:#selector(compare:)];
Sorting should be done, imo, by the database, in general. sqlite3 does support order by.