I'm trying to sort a Backbone.js collection in reverse order. There are previous replies on how to do this with integers, but none with strings.
var Chapter = Backbone.Model; var chapters = new Backbone.Collection; chapters.comparator = function(chapter) { return chapter.get("title"); }; chapters.add(new Chapter({page: 9, title: "The End"})); chapters.add(new Chapter({page: 5, title: "The Middle"})); chapters.add(new Chapter({page: 1, title: "The Beginning"})); alert(chapters.pluck('title'));
The above code sorts the chapters from A -> Z, but how do I write a comparator that sorts it from Z -> A?
You could:
0xffff
(the maximum return value of string.charCodeAt
),String.fromCharCode
to turn that back into string of "negated" charactersand that will be your sorting key.
chapters.comparator = function(chapter) { return String.fromCharCode.apply(String, _.map(chapter.get("title").split(""), function (c) { return 0xffff - c.charCodeAt(); }) ); }
And voila:
> console.log(chapters.pluck('title')); ["The Middle", "The End", "The Beginning"]
Note: if your comparison strings are long (as in 65 kb or more), you may run into trouble (see Matt's comment below). To avoid this, and speed up comparisons a bit, just use a shorter slice of your comparison string. (In the above example, you could go for chapter.get("title").slice(0, 100).split("")
instead.) How long a slice you need will depend on your application.
There are two versions of the comparator function that you can use, either the sortBy version - which was shown in the example, which takes one parameter, or sort - which you can return a more standard sort function, which the documentation says:
"sortBy" comparator functions take a model and return a numeric or string value by which the model should be ordered relative to others. "sort" comparator functions take two models, and return -1 if the first model should come before the second, 0 if they are of the same rank and 1 if the first model should come after.
So in this case, we can write a different comparator function:
var Chapter = Backbone.Model; var chapters = new Backbone.Collection; chapters.comparator = function(chapterA, chapterB) { if (chapterA.get('title') > chapterB.get('title')) return -1; // before if (chapterB.get('title') > chapterA.get('title')) return 1; // after return 0; // equal }; chapters.add(new Chapter({page: 9, title: "The End"})); chapters.add(new Chapter({page: 5, title: "The Middle"})); chapters.add(new Chapter({page: 1, title: "The Beginning"})); alert(chapters.pluck('title'));
So you should get as a response:
"The Middle", "The End", "The Beginning"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With