You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
2.3 KiB
105 lines
2.3 KiB
/*! |
|
* 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;
|
|
|