sortBy vs sortBy-deep (v5)

Revision 5 of this benchmark created by Enzo on


Description

  • vs https://github.com/staygrimm/sort-by
  • sortBy fixed

Preparation HTML

<script>
(function outer(d,l,e){function f(g,e){if(l[g])return l[g].exports;if(d[g])return h(g,f);throw Error('cannot find module "'+g+'"');}function h(g,f){var h=l[g]={exports:{}},k=d[g],m=k[2];k[0].call(h.exports,function(a){var b=d[g][1][a];return f(b?b:a)},h,h.exports,outer,d,l,e);m&&(l[m]=l[g]);return l[g].exports}var r=function(){return this}(),k;for(k in e)e[k]?r[e[k]]=f(k):f(k);f.duo=!0;f.cache=l;f.modules=d;return f})({1:[function(p,d,l){var e=p("object-path"),f;f=function(h){var f=1;"-"===h[0]&&
(f=-1,h=h.substr(1));return function(k,g){var n;e.get(k,h)<e.get(g,h)&&(n=-1);e.get(k,h)>e.get(g,h)&&(n=1);e.get(k,h)===e.get(g,h)&&(n=0);return n*f}};d.exports=function(){var h=arguments;return function(e,k){for(var g=h.length,n=0,d=0;0===n&&d<g;)n=f(h[d])(e,k),d++;return n}}},{"object-path":2}],2:[function(p,d,l){(function(e,f){"object"===typeof d&&"object"===typeof d.exports?d.exports=f():"function"===typeof define&&define.amd?define([],f):e.objectPath=f()})(this,function(){function e(a){if(!a)return!0;
if(!d(a)||0!==a.length)for(var b in a)if(p.call(a,b))return!1;return!0}function f(a){return"number"===typeof a||"[object Number]"===l.call(a)}function h(a){return"string"===typeof a||"[object String]"===l.call(a)}function d(a){return"object"===typeof a&&"number"===typeof a.length&&"[object Array]"===l.call(a)}function k(a){var b=parseInt(a);return b.toString()===a?b:a}function g(a,b,c,q){f(b)&&(b=[b]);if(e(b))return a;if(h(b))return g(a,b.split("."),c,q);var d=k(b[0]);if(1===b.length)return b=a[d],
void 0!==b&&q||(a[d]=c),b;void 0===a[d]&&(f(d)?a[d]=[]:a[d]={});return g(a[d],b.slice(1),c,q)}function n(a,b){f(b)&&(b=[b]);if(!e(a)){if(e(b))return a;if(h(b))return n(a,b.split("."));var c=k(b[0]),g=a[c];if(1===b.length)void 0!==g&&(d(a)?a.splice(c,1):delete a[c]);else if(void 0!==a[c])return n(a[c],b.slice(1));return a}}var l=Object.prototype.toString,p=Object.prototype.hasOwnProperty,m={ensureExists:function(a,b,c){return g(a,b,c,!0)},set:function(a,b,c,d){return g(a,b,c,d)},insert:function(a,
b,c,f){var e=m.get(a,b);f=~~f;d(e)||(e=[],m.set(a,b,e));e.splice(f,0,c)},empty:function(a,b){if(e(b))return a;if(!e(a)){var c,g;if(!(c=m.get(a,b)))return a;if(h(c))return m.set(a,b,"");if("boolean"===typeof c||"[object Boolean]"===l.call(c))return m.set(a,b,!1);if(f(c))return m.set(a,b,0);if(d(c))c.length=0;else if("object"===typeof c&&"[object Object]"===l.call(c))for(g in c)p.call(c,g)&&delete c[g];else return m.set(a,b,null)}},push:function(a,b){var c=m.get(a,b);d(c)||(c=[],m.set(a,b,c));c.push.apply(c,
Array.prototype.slice.call(arguments,2))},coalesce:function(a,b,c){for(var d,e=0,f=b.length;e<f;e++)if(void 0!==(d=m.get(a,b[e])))return d;return c},get:function(a,b,c){f(b)&&(b=[b]);if(e(b))return a;if(e(a))return c;if(h(b))return m.get(a,b.split("."),c);var d=k(b[0]);return 1===b.length?void 0===a[d]?c:a[d]:m.get(a[d],b.slice(1),c)},del:function(a,b){return n(a,b)}};return m})},{}]},{},{1:"sortBy"});

var sortBydeep=Array.prototype.sortBydeep=function(){var a=function(a,b){try{for(var c=0;c<b.length-1;c++)a=a[b[c]];return a[b[c]]}catch(d){return a}};return function(){var b,c,d,e,f,g,h=arguments.length-1,i=1,j=arguments[0];for(this instanceof Array&&(j=this,i=0);h>=i;h--)b=1,g=arguments[h].split("."),d=g.length>1,c=g[0],"-"!=c.charAt(0)||j[0].hasOwnProperty(c)||(b=-1,c=g[0]=c.slice(1)),j.sort(function(h,i){return d?(e=a(h,g),f=a(i,g)):(e=h[c],f=i[c]),e===f?0:(type=typeof e,"string"==type?(e>f?1:-1)*b:"number"==type||"boolean"==type||e instanceof Date?(e-f)*b:1)});return j}}();

var sortBy2 = (function(){
        

        var get = function(obj, path) {

                try {
                        for (var i = 0; i<path.length-1; i++)
                                obj = obj[ path[i] ];

                        return obj[ path[i] ];
                } catch(e) {
                        return obj;
                }

        };


        return function() {

                var property, one, two, diff, i=1, total=arguments.length, array=arguments[0], properties=[];

                // If is called as method of the array itself
                if (this instanceof Array) {
                        array = this;
                        i = 0;
                }


                // Storing the properties needed for the search
                for (; i<total; i++ ) {

                        property = {};
                        property.asc = 1;
                        property.path = arguments[i].split('.');
                        property.isdeep = property.path.length > 1;
                        property.name = property.path[0];

                        // Reverse
                        if ( property.name.charAt(0) == '-' && !array[0].hasOwnProperty(property.name) ) {
                                property.asc = -1;
                                property.name = property.path[0] = property.name.slice(1);
                        }

                        properties.push( property );

                }





                array.sort(function check( a, b, j ) {

                        if (typeof j != 'number')
                                j = 0;
                        else if ( j>(i-1) )
                                return 0;

                        property = properties[j];

                        if ( property.isdeep ) {
                                one = get(a, property.path);
                                two = get(b, property.path);
                        }
                        else {
                                one = a[property.name];
                                two = b[property.name];
                        }




                        if ( one === two )
                                diff = 0;

                        else if ( typeof one == 'string' )
                                diff = ((one > two) ? 1 : -1) * property.asc;

                        else if ( typeof one == 'number' || typeof one == 'boolean' || one instanceof Date )
                                diff = (one - two) * property.asc;

                        else
                                return 1;


                        return diff || check( a, b, j+1 );

                });


                return array;

        }

})();
</script>

Setup

var data = [
        {id:4, name:"Josema", age:34, work: {isworking:true} }, 
        {id:5, name:"Enzo", age:29, work: {isworking:true} }, 
        {id:2, name:"Josema", age:29, work: {isworking:false} }, 
        {id:1, name:"Enzo", age:29, work: {isworking:false} }, 
        {id:3, name:"Enzo", age:34, work: {isworking:false} }
    ];

Test runner

Ready to run.

Testing in
TestOps/sec
sortBy
sortBydeep(data.slice(0), 'name', 'work.isworking', '-age', 'id' );
ready
sortBy fixed
sortBy2(data.slice(0), 'name', 'work.isworking', '-age', 'id' );
ready
sort-by
data.slice(0).sort(sortBy('name', 'work.isworking', '-age', 'id'));
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.