magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.79k stars 1.79k forks source link

Add case insensitive sort option #135

Open dbowen opened 12 years ago

dbowen commented 12 years ago

It’d be nice have a case insensitive version of all the fetching functions with a sort option. Currently we have to do this with a predicate from what I’ve seen, but it’d be nice to have this option as I don’t believe its too uncommon.

magicalpanda commented 12 years ago

Unless you're exposing predicates to the user, I don't think it's too much to ask that you have the case of your own properties correct in your searches and sorts. Besides, if you made case insensitivity the default, by default all searches and sorts would take longer. The goal is to make coding easier with as little impact on performance as possible.

Saul Mora Founding Panda saul@magicalpanda.com

On Jan 20, 2012, at 5:21 PM, dbowen wrote:

It'd be nice have a case insensitive version of all the fetching functions with a sort option. Currently we have to do this with a predicate from what I've seen, but it'd be nice to have this option as I don't believe its too uncommon.


Reply to this email directly or view it on GitHub: https://github.com/magicalpanda/MagicalRecord/issues/135

dbowen commented 12 years ago

I think I miscommunicated, it would be for the ordering of the results, not on the property names themselves. It's more of a suggestion for simplicity rather than necessary, as we can do it with predicates. However, I think we may end up writing it in for ourselves anyway as an option just for simplicity. Is this something you would want a pull request for?

As an example, lets assume we have an inventory system. The user enters various details, mainly product name. Regardless of wether or not the user entered the data as "Pencil" or "pencil", all things starting with the letter 'p' should be in the same area of the tableview based on the product name.

magicalpanda commented 12 years ago

Right, honestly, I'm seeing the same type of sorting issue myself in an app I'm writing. I haven't come up with something that allows case insensitive sorting yet, but if you have something that can work at the database level (because it's faster), I'm open to adding it....

Saul Mora Founding Panda saul@magicalpanda.com

On Jan 20, 2012, at 5:51 PM, dbowen wrote:

I think I miscommunicated, it would be for the ordering of the results, not on the property names themselves. It's more of a suggestion, I think we may end up writing it in for ourselves anyway as an option just for simplicity.

As an example, lets assume we have an inventory system. The user enters various details, mainly product name. Regardless of wether or not the user entered the data as "Pencil" or "pencil", all things starting with the letter 'p' should be in the same area of the tableview based on the product name.


Reply to this email directly or view it on GitHub: https://github.com/magicalpanda/MagicalRecord/issues/135#issuecomment-3593342

runmad commented 12 years ago

I ran into the issue today too. I have a lists of contacts that are pulled from LinkedIn. Out of about 130 contacts, 2 people have written their first and last name in lowercase.

I use: self.fetchedResultsController = [Contact fetchAllSortedBy:@"firstName" ascending:YES withPredicate:nil groupBy:@"firstName" delegate:self];

And this gives me a list of my contacts sorted by first name, but divides the list up into two, the longer one which has contacts that use uppercase letter for their first name and then at the bottom, the two contacts that have used lower case for their names at the bottom (sorted alphabetically by first name).

dbowen commented 12 years ago

I asked Apple about this at WWDC, and their recommended solution is to create a normalized attribute to sort on. Not exactly ideal, but it works for now.

In your case I would add the attribute normalizedFirstName, then override the setter for firstName to also set normalizedFirstName as [firstName lowercaseString].

runmad commented 12 years ago

Thanks for the follow-up. Strange case, I can't imagine having to sort like this at all, but maybe I am biased due to my use-case.

mbigatti commented 11 years ago

Hi. I ran into the same issue. I have a simple lookup table of names that I'd like to order without considering the case. I could follow Apple suggestion and duplicate the name field to store the normalized version, but it seems a waste of space and add complexity to the model. I'm not so happy with it.

How about a solution like this one: https://github.com/RestKit/RestKit/issues/702

Regards, MB

PS: thanks, MR is awesome

casademora commented 11 years ago

I don't think that is wasteful. You can manage the denormalized data easily with Core Data using the awakeFromInsert and willSave methods. And if it lets you search your data faster, then it's the tradeoff you'll need to get the job done.

The solution you pointed to has a different tradeoff. Since it's using a property on the object to do the grouping, it's all done in memory, in "Object Space" and not in the sqlite database. This is going to be slower overall given all the objects that could be grouped at any one fetch. Try denormalizing your data. It's worked for me in the past, and it is less wasteful of user space than you may realize.

On Jun 22, 2013, at 1:00 PM, mbigatti notifications@github.com wrote:

Hi. I ran into the same issue. I have a simple lookup table of names that I'd like to order without considering the case. I could follow Apple suggestion and duplicate the name field to store the normalized version, but it seems a waste of space and add complexity to the model. I'm not so happy with it.

How about a solution like this one: RestKit/RestKit#702

Regards, MB

PS: thanks, MR is awesome

— Reply to this email directly or view it on GitHub.

ethanparker commented 10 years ago

I ran into the same issue. MR_finadAllSortedByCaseinsensitive would be great.

mohith commented 10 years ago

This might be against software engineering concepts and mess up performance

But to get things done.

I am directly accessing (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id<NSFetchedResultsControllerDelegate>)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context; from category method in NSManagedObject (MagicalFinders_CustomRequest)

and

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ IN planets.galaxy.ID", self.galaxy.ID];
NSFetchRequest *request = [Planets MR_requestAllSortedBy:nil
                                                ascending:NO
                                            withPredicate:predicate
                                                inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
    request.sortDescriptors = [NSArray arrayWithObject:sort];
self.planetsFetchController = [Planets MR_fetchAllWithRequest:request
                            groupBy:nil
                           delegate:self];

cc @ethanparker

tonyarnold commented 10 years ago

@mohith that's just fine, and exactly what I would have done.

Assuming it works. Keep in mind that the block-based sort descriptors won't work against a SQLite store — I'm unsure of whether the same is true of the selector-based sort descriptors such as the one you've provided here.

Does it work, and are you using a SQLite based persistent store?

mohith commented 10 years ago

@tonyarnold Yep it worked.I am using SQLite based persistent store (NSSQLiteStoreType)

andriyslyusar commented 9 years ago

Merge from @naqi could be the reason of crash:

-[__NSDate localizedCaseInsensitiveCompare:]: unrecognized selector sent to instance 0x17000bc50

I think better to introduce new MR_fetchAll... with NSSortDescriptor as parameter.