lodash orderby with null and real values not ordering correctly

一个人想着一个人 提交于 2019-12-19 05:18:56

问题


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?


回答1:


In _.orderBy() iteratees 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, that 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 to 0. (and therefore will be displayed at last because of desc ordering on the propertyName field). In such case, propertyName2 will therefore determine the ordering.




回答2:


The code I needed looks like this...

_.orderBy(this.myArray, [( o ) => { return o.myProperty || ''}], ['desc']); 



回答3:


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']
  )



回答4:


mine looks like this. PropName and sort are both variables in my solution

return _.orderBy( myarray, [
  ( data ) => {
    if ( data[propName] === null ) {
        data[propName] = "";
    }
    return data[propName].toLowerCase();
    }
 ], [sort] );

I wanted tolowercase because otherwise the sorting is not correct if different casings




回答5:


This will put bad values at the bottom, and it differentiates between numbers and strings.

const items = [] // some list

const goodValues = isAscending => ({ value }) => {
    if (typeof value !== 'string' && isNaN(value)) {
        return isAscending ? Infinity : -Infinity
    }

    return value || ''
}

const sortedItems = orderBy(
    items,
    [goodValues(isAscending), 'value'],
    [isAscending ? 'asc' : 'desc']
)



回答6:


This worked for me

orders = [{id : "1", name : "test"}, {id : "1"}];
sortBy = ["id", "name"];
orderby(
            orders,
            sortBy.map(s => {
                return (r: any) => {
                    return r[s] ? r[s] : "";
                };
            })),
        );


来源:https://stackoverflow.com/questions/41138820/lodash-orderby-with-null-and-real-values-not-ordering-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!