I have an Angular 2 typescript application that is using lodash for various things.
I have an array of objects that I am ordering using a property in the object...
_.orderBy(this.myArray, ['propertyName'], ['desc']);
This works well however my problem is that sometimes 'propertyName' can have a null value. These are ordered as the first item in a descending list, the highest real values then follow.
I want to make these null values appear last in the descending ordering.
I understand why the nulls come first.
Does anyone know how to approach this?
groupBy , but it does preserve the order of array-like collections, and that's probably unlikely to change. So the sub-items within groups would retain their original ordering, but the grouped key ordering may change, because they are object properties.
orderBy() method is similar to _. sortBy() method except that it allows the sort orders of the iterates to sort by. If orders are unspecified, then all values are sorted in ascending order otherwise order of corresponding values specifies an order of “desc” for descending or “asc” for ascending sort.
This method performs a stable sort, that is, it preserves the original sort order of equal elements. The iteratees are invoked with one argument: (value).
Lodash helps in working with arrays, strings, objects, numbers, etc. The _. isNull() method is used to find whether the value of the object is null. If the value is null then returns true otherwise it returns false.
Correspondingly, to sort NULLs first whilst ordering non-NULL values in descending order, we can use the following query: The output of the above two queries will be identical to using the NULLS FIRST / NULLS LAST options in SQLite.
Thanks. Lodash 3.10.1: Lodash 3.6.0: Correct, is now moved to the end when sorted (ascending) so when sorting descending will be at the front of the array. Could you _.compact your results before sorting?
In effect, Oracle considers NULL values larger than any non-NULL values. Unlike the above database types, SQLite considers NULLs to be smaller than any other value. If you sort a column with NULL values in ascending order, the NULLs will come first. Alternatively, if you add a DESC keyword to get a descending order, NULLs will appear last.
The _.orderBy () function's iteratees can use a method instead of a string. Check the value, and if it's null return an empty string. The check can be simple (like the one I've used), which converts all falsy values to an empty string:
The _.orderBy()
function's iteratees can use a method instead of a string. Check the value, and if it's null
return an empty string.
const myArray = [{ propertyName: 'cats' }, { propertyName: null }, { propertyName: 'dogs' }, { propertyName: 'rats' }, { propertyName: null }];
const result = _.orderBy(myArray, ({ propertyName }) => propertyName || '', ['desc']);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
The check can be simple (like the one I've used), which converts all falsy values to an empty string:
propertyName || ''
If you need a stricter check, you can use the ternary operator, and handle just null
values:
propertyName === null ? '' : propertyName
Edit: Example with multiple ordering:
const result = _.orderBy(myArray, (item) => [get(item, 'propertyName', 0), get(item, 'propertyName2')], ['desc', 'asc']);
This will order by propertyName
then propertyName2
.
If
propertyName
is undefined/null then its default order will be set to0
. (and therefore will be displayed at last because ofdesc
ordering on thepropertyName
field). In such case,propertyName2
will therefore determine the ordering.
The code I needed looks like this...
_.orderBy(this.myArray, [( o ) => { return o.myProperty || ''}], ['desc']);
Just for future reference to others you can do this to sort ascending with falsey values at the end.
items =>
orderBy(
items,
[
i => !!i.attributeToCheck,
i => {
return i.attributeToCheck ? i.attributeToCheck.toLowerCase() : ''
}
],
['desc', 'asc']
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With