No way to do complex sorts (like descending alphabetic) #488

Closed
Sidnicious opened this Issue Jul 19, 2011 · 6 comments

6 participants

@Sidnicious

Since Backbone uses Underscore-style comparators, some types of sort are not possible — like descending alphabetic.

It's also impossible to for comparators to have complex sort conditions, like “sort alphabetically, but put starred items first”.

Here is a gist that extends Backbone.Collection to use ECMAScript-style comparators, but I’m not sure to suggest for a long-term solution.

@biziclop

Yes, it would be nice to have an js-like customisable collection.compareTwo(m1,m2) function besides the existing collection.comparator(m) function.

@yuchi

Bump!

In a discussion between @kmalakoff and me this issue emerged again. AFAIK is a long lived querelle between the unelegant ES's sort and the elegant sortBy patterns.

While I still prefer sortBy's aesthetics, the ES's form is definitely more powerful, in particular when you have more than one sorting level (exempli gratia: sort by author then by title) or more than one sorting (exempli gratia: sort by title, or by aithor/title, and let the user choose).

While some workaround are possible (if every sorting level is made of strings or numbers simply concat them in order), this still forces the sorting on a different domain. In fact we can think of sortBy as (even if we know it does things in a different way):

  1. associative map domain A to domain B
  2. sort domain B objects for convenience
  3. port the sortered order back to the domain A

@kmalakoff has done some (very) interesting work on defining a _.compare method for underscore which leverages to a obj[compareFunction] if present, else compares the objects directly. In the discussion eventually came out the possibility of declaring some convention similar to what we do with isEqual, namely a compare function to be present in the compared objects.

@Sidnicious has replaced the current BB implementation with a Ecmascript compatible one. Should we consider instead an hybrid solution that checks for the presence of a comparator, and if not found (and that can be considered as an explicit "I do not want to use a sortBy pattern") defaults to a ES compliant pattern?

I'm waiting for @jashkenas and community feedback, but I personally think this issue deserves some attention.

@tbranyen
Collaborator

Technically you can use whatever sort you want. toJSON your collection, sort it, and then reset it back into the collection.

@kmalakoff

@tbranyen: I would be very concerned about performance of your proposal.

The use case that made me find this solution was: I wanted to incrementally resort a model in a list while the user was editing its name (now imagine reset-ing the collection in this case!). Two constraints: 1) the string was localized, 2) I wanted to handle the order of strings like Name1, Name 101, Name02 correctly (splitting the string from the number and correctly combining the sort results).

In a related note, I submitted a pull request a while ago for an sortAttribute auto-sort parameter (#625). Very useful for this type of use case.

@jashkenas
Owner

Backbone's comparator (on master) now supports sort semantics, and not just sortBy, so you can accomplish this.

comparator: function(a, b) {
  ...
@jashkenas jashkenas closed this Jan 23, 2012
@Sidnicious

Awesome!

@frank-weindel frank-weindel referenced this issue in jmorrell/backbone.obscura Oct 9, 2014
Open

Complex setSort() callback #26

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment