Skip to content

Commit ef55582

Browse files
committed
support multiple inline sortKeys in orderBy
1 parent 3904c63 commit ef55582

File tree

2 files changed

+48
-28
lines changed

2 files changed

+48
-28
lines changed

src/filters/array-filters.js

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,48 +72,60 @@ export function filterBy (arr, search, delimiter) {
7272
/**
7373
* Filter filter for arrays
7474
*
75-
* @param {String|Array<String>|Function} sortKeys
75+
* @param {String|Array<String>|Function} ...sortKeys
7676
* @param {Number} [order]
7777
*/
7878

79-
export function orderBy (arr, sortKeys, order) {
79+
export function orderBy (arr) {
80+
let comparator = null
81+
let sortKeys
8082
arr = convertArray(arr)
81-
order = (order && order < 0) ? -1 : 1
82-
let recursiveCompare = null
8383

84-
if (typeof sortKeys === 'string') {
85-
sortKeys = [sortKeys]
86-
} else if (typeof sortKeys === 'function') {
87-
recursiveCompare = function (a, b) {
88-
return sortKeys(a, b) * order
89-
}
90-
} else if (!sortKeys || (sortKeys !== true && !sortKeys.length)) {
91-
// we check if sortKeys === true because you can sort primitive values with
92-
// array | orderBy true: http://vuejs.org/api/#orderBy
93-
return arr
84+
// determine order (last argument)
85+
let args = toArray(arguments, 1)
86+
let order = args[args.length - 1]
87+
if (typeof order === 'number') {
88+
order = order < 0 ? -1 : 1
89+
args = args.length > 1 ? args.slice(0, -1) : args
90+
} else {
91+
order = 1
9492
}
9593

96-
function compare (a, b, sortKeyIndex) {
97-
const sortKey = sortKeys[sortKeyIndex]
98-
if (sortKey !== '$key') {
99-
if (isObject(a) && '$value' in a) a = a.$value
100-
if (isObject(b) && '$value' in b) b = b.$value
94+
// determine sortKeys & comparator
95+
let firstArg = args[0]
96+
if (!firstArg) {
97+
return arr
98+
} else if (typeof firstArg === 'function') {
99+
// custom comparator
100+
comparator = function (a, b) {
101+
return firstArg(a, b) * order
102+
}
103+
} else {
104+
// string keys. flatten first
105+
sortKeys = Array.prototype.concat.apply([], args)
106+
comparator = function (a, b, i) {
107+
i = i || 0
108+
return i >= sortKeys.length - 1
109+
? baseCompare(a, b, i)
110+
: baseCompare(a, b, i) || comparator(a, b, i + 1)
101111
}
102-
a = isObject(a) ? getPath(a, sortKey) : a
103-
b = isObject(b) ? getPath(b, sortKey) : b
104-
return a === b ? 0 : a > b ? order : -order
105112
}
106113

107-
recursiveCompare = recursiveCompare || function (a, b, i) {
108-
i = i || 0
109-
if (sortKeys === true || i === sortKeys.length - 1) {
110-
return compare(a, b, i)
114+
function baseCompare (a, b, sortKeyIndex) {
115+
const sortKey = sortKeys[sortKeyIndex]
116+
if (sortKey) {
117+
if (sortKey !== '$key') {
118+
if (isObject(a) && '$value' in a) a = a.$value
119+
if (isObject(b) && '$value' in b) b = b.$value
120+
}
121+
a = isObject(a) ? getPath(a, sortKey) : a
122+
b = isObject(b) ? getPath(b, sortKey) : b
111123
}
112-
return compare(a, b, i) || recursiveCompare(a, b, i + 1)
124+
return a === b ? 0 : a > b ? order : -order
113125
}
114126

115127
// sort on a copy to avoid mutating original array
116-
return arr.slice().sort(recursiveCompare)
128+
return arr.slice().sort(comparator)
117129
}
118130

119131
/**

test/unit/specs/filters/filters_spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,18 +251,26 @@ describe('Filters', function () {
251251
// sort two keys
252252
res = filter(arr, ['a', 'b'])
253253
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
254+
res = filter(arr, 'a', 'b')
255+
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
254256

255257
// sort two keys with order
256258
res = filter(arr, ['a', 'b'], 1)
257259
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
260+
res = filter(arr, 'a', 'b', 1)
261+
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
258262

259263
// sort three keys
260264
res = filter(arr, ['a', 'b', 'c'])
261265
assertArray(res, [arr[4], arr[5], arr[1], arr[3], arr[0], arr[2]])
266+
res = filter(arr, 'a', 'b', 'c')
267+
assertArray(res, [arr[4], arr[5], arr[1], arr[3], arr[0], arr[2]])
262268

263269
// reverse two key. Preserves order when equal: 1 then 5
264270
res = filter(arr, ['a', 'b'], -1)
265271
assertArray(res, [arr[2], arr[0], arr[3], arr[1], arr[5], arr[4]])
272+
res = filter(arr, 'a', 'b', -1)
273+
assertArray(res, [arr[2], arr[0], arr[3], arr[1], arr[5], arr[4]])
266274
})
267275

268276
it('orderBy using a compare function', function () {

0 commit comments

Comments
 (0)