Skip to content

Instantly share code, notes, and snippets.

@akagomez
Forked from m-mujica/custom-comparator.js
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akagomez/c7d7111e4490e9dd49eb to your computer and use it in GitHub Desktop.
Save akagomez/c7d7111e4490e9dd49eb to your computer and use it in GitHub Desktop.
Various ideas of how to define a comparator using the sort plugin
var todos = new can.List([
{ name: 'Sleep', priority: 4, lastModified: '0/0/0', completed: false },
{ name: 'Skip', priority: 2, lastModified: '4/22/85', completed: true },
{ name: 'Hop', priority: 1, lastModified: '1/21/87', completed: true },
{ name: 'Jump', priority: 3, lastModified: '2/1/93', completed: true }
]);
// Option #1 - String
todos.attr('comparator', 'priority'); // Asc
todos.attr('comparator', '-priority'); // Desc
// Option #2 - Function
todos.attr('comparator', function (a, b) {
return a - b;
});
// Option #3 - Object
todos.attr('comparator', {
attr: 'priority',
type: 'number',
order: 'asc'
});
todos.attr('comparator.order', 'desc');
// Option #4 - Object with registered type
can.List.registerComparatorType('momentjs', function(a, b) {
return moment(a).isAfter(moment(b)) ? -1 : 1;
});
todos.attr('comparator', {
attr: 'lastModified',
type: 'momentjs',
order: 'desc'
});
// Option #5 - Array of Objects
todos.attr('comparator', [
{
attr: 'completed',
type: 'boolean',
order: 'asc'
},
{
attr: 'lastModified',
type: 'momentjs',
order: 'asc'
}
]);
@JaneOri
Copy link

JaneOri commented Jul 24, 2015

These are all great options.
I do have one thought/suggestion ( but I don't really have an opinion on which is better ):
For #4, what if we instead ( or also ) allowed the 'type' property to be a function directly, rather than a name of the registered comparator type?

todos.attr('comparator', { 
  attr: 'lastModified', 
  type: function(a, b) {
    return moment(a).isAfter(moment(b)) ? -1 : 1;     
  }, 
  order: 'desc' 
});

If we do go that way, might want to also consider renaming the 'type' property to 'function' since type: function(){...} isn't as clear/intuitive as function: 'number' would be.
( by that I mean function: 'number' is probably clear that 'number' is a reference to a library function, whereas type: function(){...} might look unexpected )

@akagomez
Copy link
Author

I considered this EXACT same thing James. Except in my case I withdrew once I considered that type: function () { ... } didn't quite make sense. But after reading your thoughts, being forced to imagine what another "key" would look like, and starting to prepare a response I came to the conclusion type: function () { ... } isn't so bad actually. We do it in the define plugin: http://canjs.com/docs/can.Map.prototype.define.type.html

I've used type: fn with the define plugin a bunch of times before and never raised an eyebrow. So maybe it's not even worth changing the key.

Still, I think an inline function would be fine to support.

@JaneOri
Copy link

JaneOri commented Jul 24, 2015

Cool, I like it. I'd much rather type "type" than type "compareFunction" ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) or a partial word like "func" anyway so I agree with you.

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