Skip to content

Commit fb876ef

Browse files
committed
Merge pull request #2562 from posva/feature/multiple-field-orderBy
Multiple field order by
2 parents a2fa045 + 04a213b commit fb876ef

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

src/filters/array-filters.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,39 @@ export function filterBy (arr, search, delimiter) {
7474
/**
7575
* Filter filter for arrays
7676
*
77-
* @param {String} sortKey
77+
* @param {String|Array<String>} sortKeys
7878
* @param {String} reverse
7979
*/
8080

81-
export function orderBy (arr, sortKey, reverse) {
81+
export function orderBy (arr, sortKeys, reverse) {
8282
arr = convertArray(arr)
83-
if (!sortKey) {
83+
let order = (reverse && reverse < 0) ? -1 : 1
84+
85+
if (typeof sortKeys === 'string') {
86+
sortKeys = [sortKeys]
87+
} else if (!sortKeys || !sortKeys.length) {
8488
return arr
8589
}
86-
var order = (reverse && reverse < 0) ? -1 : 1
87-
// sort on a copy to avoid mutating original array
88-
return arr.slice().sort(function (a, b) {
90+
91+
function compare (a, b, sortKeyIndex) {
92+
const sortKey = sortKeys[sortKeyIndex]
8993
if (sortKey !== '$key') {
9094
if (isObject(a) && '$value' in a) a = a.$value
9195
if (isObject(b) && '$value' in b) b = b.$value
9296
}
9397
a = isObject(a) ? getPath(a, sortKey) : a
9498
b = isObject(b) ? getPath(b, sortKey) : b
9599
return a === b ? 0 : a > b ? order : -order
96-
})
100+
}
101+
102+
function recursiveCompare (a, b, i) {
103+
i = i || 0
104+
if (i === sortKeys.length - 1) return compare(a, b, i)
105+
return compare(a, b, i) || recursiveCompare(a, b, i + 1)
106+
}
107+
108+
// sort on a copy to avoid mutating original array
109+
return arr.slice().sort(recursiveCompare)
97110
}
98111

99112
/**

test/unit/specs/filters/filters_spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ describe('Filters', function () {
204204
// no sort key
205205
res = filter(arr, null)
206206
expect(res).toBe(arr)
207+
res = filter(arr)
208+
expect(res).toBe(arr)
207209
})
208210

209211
it('orderBy on Object-converted array', function () {
@@ -227,6 +229,34 @@ describe('Filters', function () {
227229
res = filter(arr, 'v')
228230
assertArray(res, [arr[1], arr[2], arr[0]])
229231
})
232+
233+
it('orderBy multiple fields', function () {
234+
var filter = filters.orderBy
235+
var arr = [
236+
{ a: 1, b: 1, c: 1 }, // 0
237+
{ a: 0, b: 1, c: 1 }, // 1
238+
{ a: 1, b: 2, c: 0 }, // 2
239+
{ a: 1, b: 0, c: 0 }, // 3
240+
{ a: 0, b: 0, c: 0 }, // 4
241+
{ a: 0, b: 1, c: 0 } // 5
242+
]
243+
var res
244+
// sort two keys
245+
res = filter(arr, ['a', 'b'])
246+
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
247+
248+
// sort two keys with order
249+
res = filter(arr, ['a', 'b'], 1)
250+
assertArray(res, [arr[4], arr[1], arr[5], arr[3], arr[0], arr[2]])
251+
252+
// sort three keys
253+
res = filter(arr, ['a', 'b', 'c'])
254+
assertArray(res, [arr[4], arr[5], arr[1], arr[3], arr[0], arr[2]])
255+
256+
// reverse two key. Preserves order when equal: 1 then 5
257+
res = filter(arr, ['a', 'b'], -1)
258+
assertArray(res, [arr[2], arr[0], arr[3], arr[1], arr[5], arr[4]])
259+
})
230260
})
231261

232262
function assertArray (res, expectations) {

0 commit comments

Comments
 (0)