Skip to content

Instantly share code, notes, and snippets.

@joelpurra
Created June 24, 2012 20:17
Show Gist options
  • Select an option

  • Save joelpurra/2984763 to your computer and use it in GitHub Desktop.

Select an option

Save joelpurra/2984763 to your computer and use it in GitHub Desktop.

Revisions

  1. joelpurra revised this gist Jul 21, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion objectcomparator.joelpurra.js
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    * Copyright © 2012 Joel Purra <http://joelpurra.se/>
    * Released under MIT, BSD and GPL license. Comply with at least one.
    *
    * A jQuery plugin to create a comparator for one or more properties of an object.
    * A javascript plugin to create a comparator for one or more properties of an object.
    * Comparators are useful for sorting arrays of objects, and for general comparisons
    * in, for example, if statements.
    * The comparison is done only if the types of both objects' property matches.
  2. joelpurra revised this gist Jun 24, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion objectcomparator.joelpurra.js
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@
    * in, for example, if statements.
    * The comparison is done only if the types of both objects' property matches.
    */
    // https://gist.github.com/
    // https://gist.github.com/2984763
    //
    // USAGE
    // var comparator = JoelPurra.createComparator("propertyName");
  3. joelpurra created this gist Jun 24, 2012.
    122 changes: 122 additions & 0 deletions objectcomparator.joelpurra.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,122 @@
    /*!
    * @license ObjectComparator
    * Copyright © 2012 Joel Purra <http://joelpurra.se/>
    * Released under MIT, BSD and GPL license. Comply with at least one.
    *
    * A jQuery plugin to create a comparator for one or more properties of an object.
    * Comparators are useful for sorting arrays of objects, and for general comparisons
    * in, for example, if statements.
    * The comparison is done only if the types of both objects' property matches.
    */
    // https://gist.github.com/
    //
    // USAGE
    // var comparator = JoelPurra.createComparator("propertyName");
    // var reverseComparator = JoelPurra.createComparator("!propertyName");
    // var comparators = JoelPurra.createComparators(["propertyName1", "propertyName2"]);
    // var mixedComparators = JoelPurra.createComparators(["propertyName1", "!propertyName2"]);
    // EXAMPLE
    // var people = [
    // // Age in years, length in centimeters
    // { name: "John", age: 30, height: 187 },
    // { name: "Bilbo", age: 111, height: 112 },
    // { name: "Jane", age: 30, height: 165 },
    // { name: "Gollum", age: 570, height: 112 }
    // ];
    // // Sort by height (ascending) only
    // var shortToLongComparator = JoelPurra.createComparator("height");
    // people.sort(shortToLongComparator);
    // // => Bilbo, Gollum, Jane, John
    // // Sort by height (ascending) and age (descending)
    // var shortToLongOldToYoungComparator = JoelPurra.createComparators(["height", "!age"]);
    // people.sort(shortToLongOldToYoungComparator);
    // => Gollum, Bilbo, Jane, John
    //
    /*jslint white: true*/

    // Set up namespace, if needed
    var JoelPurra = JoelPurra || {};

    (function(namespace) {
    "use strict"; // jshint ;_;
    namespace.createNormalComparator = function(property) {
    // This comparison is not as relaxed as normal comparisons. The type is checked first, and it has
    // to match in order to continue.
    //
    // https://developer.mozilla.org/en/JavaScript/Guide/Expressions_and_Operators#Comparison_operators
    // "The operands can be numerical, string, logical, or object values.
    // Strings are compared based on standard lexicographical ordering, using Unicode values.
    // In most cases, if the two operands are not of the same type, JavaScript attempts to convert
    // the operands to an appropriate type for the comparison."
    return function(a, b) {
    if (typeof(a) !== typeof(b)) {
    throw new Error("object property \"" + property + "\" was not of the same type in a and b.");
    }

    // Using strict comparison now that the object types are the same
    if (a[property] === b[property]) {
    return 0;
    }

    if (a[property] < b[property]) {
    return -1;
    }

    if (a[property] > b[property]) {
    return 1;
    }

    throw new Error("Could not compare objects and find a matching result");
    };
    };

    namespace.createReverseComparator = function(property) {
    // Calling the parent function actually allows for properties like
    // "!!age" for "reverse reverse age comparator" ;)
    var comparator = namespace.createComparator(property);

    return function(a, b) {
    return comparator(b, a);
    };
    };

    namespace.createComparator = function(property) {
    var comparator;

    if (property.substring(0, 1) === "!") {
    property = property.substring(1);
    comparator = namespace.createReverseComparator(property);
    } else {
    comparator = namespace.createNormalComparator(property);
    }

    return comparator;
    };

    namespace.createComparators = function(properties) {
    var comparators = [],
    i;

    for (i = 0; i < properties.length; i += 1) {
    comparators.push(namespace.createComparator(properties[i]));
    }

    return function(a, b) {
    var result = 0,
    i, comparator;

    for (i = 0; i < comparators.length; i += 1) {
    comparator = comparators[i];

    result = comparator(a, b);

    if (result !== 0) {
    break;
    }
    }

    return result;
    };
    };

    }(JoelPurra));