Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to sort RLMResults using a comparison block #1265

Open
jpsim opened this issue Dec 23, 2014 · 38 comments
Open

Add ability to sort RLMResults using a comparison block #1265

jpsim opened this issue Dec 23, 2014 · 38 comments
Labels
Blocked This issue is blocked by another issue T-Enhancement

Comments

@jpsim
Copy link
Contributor

jpsim commented Dec 23, 2014

We should discuss the feasibility of this, especially around auto-updating. It may not be fully possible to do this without the ability to freeze RLMResults. If that's the case, we should add the blocked tag to this issue.

The API could look something like -[RLMResults sortedResultsUsingBlock:], which would require constructing the accessors for each item in the RLMResults and then accessing the properties accessed in the block, but it would allow people to sort in any way they like.

Thoughts @alazier @tgoyne?

@alazier
Copy link
Contributor

alazier commented Dec 24, 2014

I don't think this is something we will want to do. First it requires creating accessors for every element which can get kind of slow. Second, we will have to hold onto the sort block as long as the RLMResults exists and to reapply that block for live queries. This obviously has potential problems.

I think what we should do instead is to bring back the arrayForRange: pr and allow users to sort the NSArray using a block. The key is that users understand they are creating an array of accessors, and providing such a method where they do this explicitly is probably the best way to accomplish this.

@jpsim
Copy link
Contributor Author

jpsim commented Dec 30, 2014

I agree there are disadvantages to this approach, but it's still better than the alternatives. Unless there's another solution that we have yet to consider.

I can think of a few downsides to encouraging users to use an -[RLMResults arrayWithRange:] method for custom sorting:

  1. It's error-prone. If a user forgets to recalculate their sorted array when data changes, not only will they be accessing stale data, but they'll likely also be accessing invalid objects.
  2. It's a different interface. If users are already displaying an RLMResults and they want to tweak how it's sorted, they'll have to refactor the code accessing the data. If (when) we create a suite of UIKit extensions to back controls by Realm, we'd need to support both interfaces.
  3. It's complicating a common use case. Custom sorting is a common enough feature request that it's worth us doing once rather than many of our users independently.
  4. A user's solution is likely to be slower than ours. This is pretty safe to assume. If someone comes up with a faster way to do it, they'll hopefully share their approach with us so we can improve ours, to everyone's benefit.

This being said, there might be another approach we have yet to consider, but until then, I think an -[RLMResults sortedResultsUsingBlock:] is our best bet.

@ceeK
Copy link

ceeK commented Feb 9, 2015

Just +1ing this.

I'm currently trying to sort an array of locations by a computed 'distance' property. This 'distance' property represents the distance between the location and a user selected point.

I've been using RLMResults as my data model for my tableview, as it has sorting built in. Unfortunately, was a bit stumped and now will have to use standard arrays.

@alazier alazier added P2 Blocked This issue is blocked by another issue and removed backlog labels Feb 9, 2015
@alazier
Copy link
Contributor

alazier commented Feb 9, 2015

I guess we should add this and make clear in the docs that performance will be much worse than using sortDescriptors.

This is still blocked on core support support for manual construction and freezing of TableViews

@michaelcameron
Copy link

+1

I'm dealing with the same use case that @ceeK highlighted, sorting on a computed distance property.

@jchesne
Copy link

jchesne commented Mar 20, 2015

+1, i also need this feature.

@devpascoe
Copy link

+1 for needing it in particular with distance

@leegoodrich
Copy link

Adding my +1 to this. Even if using this came with a significant performance tradeoff versus sort descriptors (when using the feature, obviously), it has to be better than my "map to an array, run a custom sort, and regenerate on every write notification" solution I'm currently stuck with.

This would also give relief to the "sort on relationship properties" crowd (#1277) while they wait for support within sort descriptors (myself included!).

@bcapps
Copy link

bcapps commented Aug 6, 2015

+1

4 similar comments
@beloso
Copy link

beloso commented Aug 26, 2015

+1

@dltlr
Copy link

dltlr commented Jan 12, 2016

+1

@rex-remind101
Copy link

+1

@FelixLisczyk
Copy link

+1

@rex-remind101
Copy link

More specifically if we could have the localizedStandardCompare: option such as in NSFetchedResultsController that would cover 99% of cases. I'm not sure if that would be any easier to implement on its own.

@cianiandreadev
Copy link

cianiandreadev commented May 9, 2016

+1

@jimqin-alivecor
Copy link

+1

@LunaCodeGirl
Copy link

+1 here as well. Trying to sort based on one optional NSDate and another non-optional NSDate. Trying to look at whether the optional date exists and if so us it for sorting, if not fall back to the non-optional date.

@o15a3d4l11s2
Copy link

+1

1 similar comment
@peterpaulis
Copy link

+1

@peterpaulis
Copy link

you should also annotate that sortedResultsUsingDescriptors expects an array of RLMSortDescriptor not a NSSortDescriptor...

@jpsim
Copy link
Contributor Author

jpsim commented Nov 10, 2016

@peterpaulis nice catch! See #4318.

@kenneth488
Copy link

+1

1 similar comment
@weibel
Copy link

weibel commented May 11, 2017

+1

@joeFlypay
Copy link

+1 for needing it with distance.
Even if I have my own in-memory array of location id's sorted by distance, I still can't sort the RLMResults using that array, as the only thing I can sort on is dumb, stored values in the DB.
This really is a serious limitation. Seems to me that -[RLMResults sortedResultsUsingBlock:] and/or -[RLMResults sortedResultsUsingPredicate:] are a central requirement to loads and loads of use cases.

@oparinov
Copy link

+1

3 similar comments
@punithbm
Copy link

+1

@juliensagot
Copy link

+1

@aaronrogers
Copy link

+1

@trant
Copy link

trant commented Nov 2, 2018

Was this implemented already or no?

@mckapur
Copy link

mckapur commented Nov 5, 2018

+1

@mjhshin
Copy link

mjhshin commented Jan 10, 2019

+1 Stumped by the same need as mentioned above about sorting based on computed distance.

@peterpaulis
Copy link

Still no support? This is a major usecase

@Jaycyn
Copy link

Jaycyn commented Nov 12, 2019

I am also finding a need for this. +1

@emilienh
Copy link

+1 for localizedStandardCompare:

@juliensagot
Copy link

juliensagot commented Feb 12, 2020

It's been 5 years now.

It may not be fully possible to do this without the ability to freeze RLMResults

As I understand, this feature has been implemented quite recently:
Realm Database 6.0: A New Architecture and Frozen Objects

So the question is, can this feature be implemented now?

@o15a3d4l11s2
Copy link

This year it will be 10 years anniversary since the ticket was created :) Any updates/plans for this?

@Jaycyn
Copy link

Jaycyn commented Feb 7, 2024

@o15a3d4l11s2

This has been open a long time. Perhaps there is a current solution if you need to sort Realm results via a block (closure in Swift). Would this suffice?

Assume a Person object

class Person: Object {
   @Persisted var name = ""
}

and then to query for person objects sorted by name - note the .sorted(by: { closure }

let sortedPersons = realm.objects(Person.self).sorted(by: { lhs, rhs in
    return lhs.name < rhs.name
})

sortedPersons.forEach { person in
    print(person.name)
}

and the output would be Person objects sorted by name (or whatever property or comparison you choose)

I think that meets the requirements of the git title "Add ability to sort RLMResults using a comparison block"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Blocked This issue is blocked by another issue T-Enhancement
Projects
None yet
Development

No branches or pull requests