106 lines
2.3 KiB
JavaScript
106 lines
2.3 KiB
JavaScript
|
/*!
|
||
|
* array-sort <https://github.com/jonschlinkert/array-sort>
|
||
|
*
|
||
|
* Copyright (c) 2015-2017, Jon Schlinkert.
|
||
|
* Released under the MIT License.
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
var defaultCompare = require('default-compare');
|
||
|
var typeOf = require('kind-of');
|
||
|
var get = require('get-value');
|
||
|
|
||
|
/**
|
||
|
* Sort an array of objects by one or more properties.
|
||
|
*
|
||
|
* @param {Array} `arr` The Array to sort.
|
||
|
* @param {String|Array|Function} `props` One or more object paths or comparison functions.
|
||
|
* @param {Object} `opts` Pass `{ reverse: true }` to reverse the sort order.
|
||
|
* @return {Array} Returns a sorted array.
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function arraySort(arr, props, opts) {
|
||
|
if (arr == null) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
if (!Array.isArray(arr)) {
|
||
|
throw new TypeError('array-sort expects an array.');
|
||
|
}
|
||
|
|
||
|
if (arguments.length === 1) {
|
||
|
return arr.sort();
|
||
|
}
|
||
|
|
||
|
var args = flatten([].slice.call(arguments, 1));
|
||
|
|
||
|
// if the last argument appears to be a plain object,
|
||
|
// it's not a valid `compare` arg, so it must be options.
|
||
|
if (typeOf(args[args.length - 1]) === 'object') {
|
||
|
opts = args.pop();
|
||
|
}
|
||
|
return arr.sort(sortBy(args, opts));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Iterate over each comparison property or function until `1` or `-1`
|
||
|
* is returned.
|
||
|
*
|
||
|
* @param {String|Array|Function} `props` One or more object paths or comparison functions.
|
||
|
* @param {Object} `opts` Pass `{ reverse: true }` to reverse the sort order.
|
||
|
* @return {Array}
|
||
|
*/
|
||
|
|
||
|
function sortBy(props, opts) {
|
||
|
opts = opts || {};
|
||
|
|
||
|
return function compareFn(a, b) {
|
||
|
var len = props.length, i = -1;
|
||
|
var result;
|
||
|
|
||
|
while (++i < len) {
|
||
|
result = compare(props[i], a, b);
|
||
|
if (result !== 0) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (opts.reverse === true) {
|
||
|
return result * -1;
|
||
|
}
|
||
|
return result;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Compare `a` to `b`. If an object `prop` is passed, then
|
||
|
* `a[prop]` is compared to `b[prop]`
|
||
|
*/
|
||
|
|
||
|
function compare(prop, a, b) {
|
||
|
if (typeof prop === 'function') {
|
||
|
// expose `compare` to custom function
|
||
|
return prop(a, b, compare.bind(null, null));
|
||
|
}
|
||
|
// compare object values
|
||
|
if (prop && typeof a === 'object' && typeof b === 'object') {
|
||
|
return compare(null, get(a, prop), get(b, prop));
|
||
|
}
|
||
|
return defaultCompare(a, b);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Flatten the given array.
|
||
|
*/
|
||
|
|
||
|
function flatten(arr) {
|
||
|
return [].concat.apply([], arr);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Expose `arraySort`
|
||
|
*/
|
||
|
|
||
|
module.exports = arraySort;
|