Skip to content

Commit 38e12d8

Browse files
committed
added options.nullRank and undefinedRank
1 parent 29e85f6 commit 38e12d8

5 files changed

Lines changed: 157 additions & 18 deletions

File tree

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,15 @@ Please visit [the sort-array wiki](https://github.com/75lb/sort-array/wiki) for
139139
### sort-array
140140
Isomorphic, load-anywhere function to sort an array by scalar, deep or computed values in any standard or custom order.
141141

142-
**Example**
142+
**Example**
143143
```js
144144
const sortArray = require('sort-array')
145145
```
146146
<a name="exp_module_sort-array--sortArray"></a>
147147

148148
#### sortArray(array, [options]) ⇒ <code>Array</code> ⏏
149-
**Kind**: Exported function
150-
**Returns**: <code>Array</code> - Returns the array that was passed in.
149+
**Kind**: Exported function
150+
**Returns**: <code>Array</code> - Returns the array that was passed in.
151151

152152
| Param | Type | Description |
153153
| --- | --- | --- |
@@ -157,6 +157,8 @@ const sortArray = require('sort-array')
157157
| [options.order] | <code>Array.&lt;string&gt;</code> | One or more sort orders. Specify `asc`, `desc` or a property name from the `options.customOrders` object. |
158158
| [options.customOrders] | <code>object</code> | A dictionary object containing one or more custom orders. Each custom order value must be an array defining the order expected values must be sorted in. |
159159
| [options.computed] | <code>object</code> | A dictionary object containing one or more computed field functions. The function will be invoked once per item in the array. Each invocation will receive the array item as input and must return a primitive value by which the array can be sorted. |
160+
| [options.nullRank] | <code>number</code> | Configures whether `null` values will be sorted before or after defined values. Set to `-1` for before, `1` for after. Defaults to `1`. |
161+
| [options.undefinedRank] | <code>number</code> | Configures whether `undefined` values will be sorted before or after defined values. Set to `-1` for before, `1` for after. Defaults to `1`. |
160162

161163

162164
## Load anywhere

dist/index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,12 @@
356356
*/
357357
function sortArray (arr, options = {}) {
358358
options = Object.assign(
359-
{ computed: {}, customOrders: {} },
359+
{
360+
computed: {},
361+
customOrders: {},
362+
nullRank: 1,
363+
undefinedRank: 1
364+
},
360365
options
361366
);
362367
arr.sort(getCompareFunc(options));
@@ -403,13 +408,13 @@
403408
? 1
404409
: 0;
405410
} else if (t.isNull(x) && t.isDefinedValue(y)) {
406-
result = 1;
411+
result = options.nullRank;
407412
} else if (t.isUndefined(x) && t.isDefinedValue(y)) {
408-
result = 1;
413+
result = options.undefinedRank;
409414
} else if (t.isNull(y) && t.isDefinedValue(x)) {
410-
result = -1;
415+
result = -options.nullRank;
411416
} else if (t.isUndefined(y) && t.isDefinedValue(x)) {
412-
result = -1;
417+
result = -options.undefinedRank;
413418
} else {
414419
result = x < y ? -1 : x > y ? 1 : 0;
415420
if (currOrder === 'desc') {

dist/index.mjs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,12 @@ var t = {
350350
*/
351351
function sortArray (arr, options = {}) {
352352
options = Object.assign(
353-
{ computed: {}, customOrders: {} },
353+
{
354+
computed: {},
355+
customOrders: {},
356+
nullRank: 1,
357+
undefinedRank: 1
358+
},
354359
options
355360
);
356361
arr.sort(getCompareFunc(options));
@@ -397,13 +402,13 @@ function getCompareFunc (options = {}) {
397402
? 1
398403
: 0;
399404
} else if (t.isNull(x) && t.isDefinedValue(y)) {
400-
result = 1;
405+
result = options.nullRank;
401406
} else if (t.isUndefined(x) && t.isDefinedValue(y)) {
402-
result = 1;
407+
result = options.undefinedRank;
403408
} else if (t.isNull(y) && t.isDefinedValue(x)) {
404-
result = -1;
409+
result = -options.nullRank;
405410
} else if (t.isUndefined(y) && t.isDefinedValue(x)) {
406-
result = -1;
411+
result = -options.undefinedRank;
407412
} else {
408413
result = x < y ? -1 : x > y ? 1 : 0;
409414
if (currOrder === 'desc') {

index.mjs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ import t from 'typical/index.mjs'
1717
* @param {string[]} [options.order] - One or more sort orders. Specify `asc`, `desc` or a property name from the `options.customOrders` object.
1818
* @param {object} [options.customOrders] - A dictionary object containing one or more custom orders. Each custom order value must be an array defining the order expected values must be sorted in.
1919
* @param {object} [options.computed] - A dictionary object containing one or more computed field functions. The function will be invoked once per item in the array. Each invocation will receive the array item as input and must return a primitive value by which the array can be sorted.
20+
* @param {number} [options.nullRank] - Configures whether `null` values will be sorted before or after defined values. Set to `-1` for before, `1` for after. Defaults to `1`.
21+
* @param {number} [options.undefinedRank] - Configures whether `undefined` values will be sorted before or after defined values. Set to `-1` for before, `1` for after. Defaults to `1`.
2022
* @returns {Array} Returns the array that was passed in.
2123
* @alias module:sort-array
2224
*/
2325
function sortArray (arr, options = {}) {
2426
options = Object.assign(
25-
{ computed: {}, customOrders: {} },
27+
{
28+
computed: {},
29+
customOrders: {},
30+
nullRank: 1,
31+
undefinedRank: 1
32+
},
2633
options
2734
)
2835
arr.sort(getCompareFunc(options))
@@ -69,13 +76,13 @@ function getCompareFunc (options = {}) {
6976
? 1
7077
: 0
7178
} else if (t.isNull(x) && t.isDefinedValue(y)) {
72-
result = 1
79+
result = options.nullRank
7380
} else if (t.isUndefined(x) && t.isDefinedValue(y)) {
74-
result = 1
81+
result = options.undefinedRank
7582
} else if (t.isNull(y) && t.isDefinedValue(x)) {
76-
result = -1
83+
result = -options.nullRank
7784
} else if (t.isUndefined(y) && t.isDefinedValue(x)) {
78-
result = -1
85+
result = -options.undefinedRank
7986
} else {
8087
result = x < y ? -1 : x > y ? 1 : 0
8188
if (currOrder === 'desc') {

test/sort-falsy.mjs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,126 @@ async function getTom () {
169169
a.deepStrictEqual(result, expected)
170170
})
171171

172+
tom.test('nullRank: -1', function () {
173+
const fixture = [
174+
{ a: 4, b: null, c: 3 },
175+
{ a: 4, b: 2, c: null },
176+
{ a: 2, b: 2, c: 3 },
177+
{ a: 2, b: 2, c: 2 },
178+
{ a: null, b: 3, c: 4 },
179+
{ a: null, b: null, c: 4 },
180+
{ a: null, b: 2, c: 4 },
181+
{ a: 3, b: 3, c: 3 },
182+
{ a: 4, b: 3, c: null }
183+
]
184+
const expected = [
185+
{ a: null, b: null, c: 4 },
186+
{ a: null, b: 2, c: 4 },
187+
{ a: null, b: 3, c: 4 },
188+
{ a: 2, b: 2, c: 2 },
189+
{ a: 2, b: 2, c: 3 },
190+
{ a: 3, b: 3, c: 3 },
191+
{ a: 4, b: null, c: 3 },
192+
{ a: 4, b: 2, c: null },
193+
{ a: 4, b: 3, c: null },
194+
]
195+
196+
const by = ['a', 'b', 'c']
197+
const order = ['asc', 'asc', 'asc']
198+
const result = sortArray(fixture, { by, order, nullRank: -1 })
199+
a.deepStrictEqual(result, expected)
200+
})
201+
202+
tom.test('nullRank: 1', function () {
203+
const fixture = [
204+
{ a: 4, b: null, c: 3 },
205+
{ a: 4, b: 2, c: null },
206+
{ a: 2, b: 2, c: 3 },
207+
{ a: 2, b: 2, c: 2 },
208+
{ a: null, b: 3, c: 4 },
209+
{ a: null, b: null, c: 4 },
210+
{ a: null, b: 2, c: 4 },
211+
{ a: 3, b: 3, c: 3 },
212+
{ a: 4, b: 3, c: null }
213+
]
214+
const expected = [
215+
{ a: 2, b: 2, c: 2 },
216+
{ a: 2, b: 2, c: 3 },
217+
{ a: 3, b: 3, c: 3 },
218+
{ a: 4, b: 2, c: null },
219+
{ a: 4, b: 3, c: null },
220+
{ a: 4, b: null, c: 3 },
221+
{ a: null, b: 2, c: 4 },
222+
{ a: null, b: 3, c: 4 },
223+
{ a: null, b: null, c: 4 },
224+
]
225+
226+
const by = ['a', 'b', 'c']
227+
const order = ['asc', 'asc', 'asc']
228+
const result = sortArray(fixture, { by, order, nullRank: 1 })
229+
a.deepStrictEqual(result, expected)
230+
})
231+
232+
tom.test('undefinedRank: -1', function () {
233+
const fixture = [
234+
{ a: 4, b: undefined, c: 3 },
235+
{ a: 4, b: 2, c: undefined },
236+
{ a: 2, b: 2, c: 3 },
237+
{ a: 2, b: 2, c: 2 },
238+
{ a: undefined, b: 3, c: 4 },
239+
{ a: undefined, b: undefined, c: 4 },
240+
{ a: undefined, b: 2, c: 4 },
241+
{ a: 3, b: 3, c: 3 },
242+
{ a: 4, b: 3, c: undefined }
243+
]
244+
const expected = [
245+
{ a: undefined, b: undefined, c: 4 },
246+
{ a: undefined, b: 2, c: 4 },
247+
{ a: undefined, b: 3, c: 4 },
248+
{ a: 2, b: 2, c: 2 },
249+
{ a: 2, b: 2, c: 3 },
250+
{ a: 3, b: 3, c: 3 },
251+
{ a: 4, b: undefined, c: 3 },
252+
{ a: 4, b: 2, c: undefined },
253+
{ a: 4, b: 3, c: undefined },
254+
]
255+
256+
const by = ['a', 'b', 'c']
257+
const order = ['asc', 'asc', 'asc']
258+
const result = sortArray(fixture, { by, order, undefinedRank: -1 })
259+
a.deepStrictEqual(result, expected)
260+
})
261+
262+
tom.test('undefinedRank: 1', function () {
263+
const fixture = [
264+
{ a: 4, b: undefined, c: 3 },
265+
{ a: 4, b: 2, c: undefined },
266+
{ a: 2, b: 2, c: 3 },
267+
{ a: 2, b: 2, c: 2 },
268+
{ a: undefined, b: 3, c: 4 },
269+
{ a: undefined, b: undefined, c: 4 },
270+
{ a: undefined, b: 2, c: 4 },
271+
{ a: 3, b: 3, c: 3 },
272+
{ a: 4, b: 3, c: undefined }
273+
]
274+
const expected = [
275+
{ a: 2, b: 2, c: 2 },
276+
{ a: 2, b: 2, c: 3 },
277+
{ a: 3, b: 3, c: 3 },
278+
{ a: 4, b: 2, c: undefined },
279+
{ a: 4, b: 3, c: undefined },
280+
{ a: 4, b: undefined, c: 3 },
281+
{ a: undefined, b: 2, c: 4 },
282+
{ a: undefined, b: 3, c: 4 },
283+
{ a: undefined, b: undefined, c: 4 },
284+
]
285+
286+
const by = ['a', 'b', 'c']
287+
const order = ['asc', 'asc', 'asc']
288+
const result = sortArray(fixture, { by, order, undefinedRank: 1 })
289+
a.deepStrictEqual(result, expected)
290+
})
291+
172292
return tom
173293
}
174294

0 commit comments

Comments
 (0)