From 79dc90dfcb743b57d348a0ac134ff9694ae937e7 Mon Sep 17 00:00:00 2001 From: Ryan Homer Date: Tue, 1 May 2018 12:22:50 -0700 Subject: [PATCH] Allow compareMultiple to accept compare functions in addition to order strings (#3764) --- .internal/compareMultiple.js | 13 +++++++------ orderBy.js | 10 +++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.internal/compareMultiple.js b/.internal/compareMultiple.js index 81b742057..b29b905c5 100644 --- a/.internal/compareMultiple.js +++ b/.internal/compareMultiple.js @@ -11,7 +11,7 @@ import compareAscending from './compareAscending.js' * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. + * @param {(string|function)[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ function compareMultiple(object, other, orders) { @@ -22,13 +22,14 @@ function compareMultiple(object, other, orders) { const ordersLength = orders.length while (++index < length) { - const result = compareAscending(objCriteria[index], othCriteria[index]) + var order = index < ordersLength ? orders[index] : null + var cmpFn = (order && typeof order === 'function') ? order: compareAscending + var result = cmpFn(objCriteria[index], othCriteria[index]) if (result) { - if (index >= ordersLength) { - return result + if (order && typeof order !== 'function') { + return result * (order == 'desc' ? -1 : 1) } - const order = orders[index] - return result * (order == 'desc' ? -1 : 1) + return result } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications diff --git a/orderBy.js b/orderBy.js index f4acd902a..4bb2112ef 100644 --- a/orderBy.js +++ b/orderBy.js @@ -5,13 +5,14 @@ import baseOrderBy from './.internal/baseOrderBy.js' * orders of the iteratees to sort by. If `orders` is unspecified, all values * are sorted in ascending order. Otherwise, specify an order of "desc" for * descending or "asc" for ascending sort order of corresponding values. + * You may also specify a compare function for an order. * * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[identity]] * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. + * @param {(string|function)[]} [orders] The sort orders of `iteratees`. * @returns {Array} Returns the new sorted array. * @see reverse * @example @@ -26,6 +27,13 @@ import baseOrderBy from './.internal/baseOrderBy.js' * // Sort by `user` in ascending order and by `age` in descending order. * orderBy(users, ['user', 'age'], ['asc', 'desc']) * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + * + * // Sort by `user` then by `age` using custom compare functions for each + * orderBy(users, ['user', 'age'], [ + * (a, b) => a.localeCompare(b, 'de', { sensitivity: 'base' }), + * (a, b) => a - b, + * ]) + * */ function orderBy(collection, iteratees, orders) { if (collection == null) {