Skip to content

Commit 820dcc9

Browse files
authored
Ensure null values sort last (#148)
1 parent a06efb0 commit 820dcc9

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

src/lib.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,22 @@ export function sorted_items(items, sort, sortings) {
152152
}
153153

154154
if (sort.field) {
155-
return orderBy(items, sort.field, sort.order || 'asc');
155+
const fields = Array.isArray(sort.field) ? sort.field : [sort.field];
156+
const orders = Array.isArray(sort.order) ? sort.order : [sort.order || 'asc'];
157+
158+
// push null/undefined to the end for each field by prefixing with a boolean iteratee
159+
const iteratees = [];
160+
const iterateeOrders = [];
161+
162+
fields.forEach((field, idx) => {
163+
iteratees.push((item) => (item[field] === null || item[field] === undefined ? 1 : 0));
164+
iterateeOrders.push('asc'); // keep non-null before nulls
165+
166+
iteratees.push(field);
167+
iterateeOrders.push(orders[idx] || 'asc');
168+
});
169+
170+
return orderBy(items, iteratees, iterateeOrders);
156171
}
157172

158173
return items;

tests/sortingSpec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ describe('aggregations', function () {
2222
},
2323
];
2424

25+
const itemsWithNulls = [
26+
{ name: 'movie1', rating: null },
27+
{ name: 'movie2', rating: 5 },
28+
{ name: 'movie3', rating: null },
29+
{ name: 'movie4', rating: 3 },
30+
];
31+
2532
it('makes items sorting', function test(done) {
2633
const sortings = {
2734
name_asc: {
@@ -72,6 +79,24 @@ describe('aggregations', function () {
7279
'movie7',
7380
'movie2',
7481
]);
82+
83+
// nulls should be last regardless of order
84+
const nullSortings = {
85+
rating_desc: {
86+
field: 'rating',
87+
order: 'desc',
88+
},
89+
rating_asc: {
90+
field: 'rating',
91+
order: 'asc',
92+
},
93+
};
94+
95+
result = sorted_items(itemsWithNulls, 'rating_desc', nullSortings);
96+
assert.deepEqual(map(result, 'rating'), [5, 3, null, null]);
97+
98+
result = sorted_items(itemsWithNulls, 'rating_asc', nullSortings);
99+
assert.deepEqual(map(result, 'rating'), [3, 5, null, null]);
75100
done();
76101
});
77102
});

0 commit comments

Comments
 (0)