简体   繁体   中英

Using lodash orderBy or sortBy and handling null values

I'm having trouble using sortBy or orderBy to sort an array array by name where name may be null. I'd like to be able to sort by name in ascending order (AZ) with the null values at the end.

Currently my code:

_sortBy(myArray, objectA => objectA.name)

Will return the null values at the beginning, then proceed to sort the objects with a name value after.

Thank you in advance for any help.

Lets assume your input is this:

var data=[
   {name:'John Alexov'},
   {name:null},
   {name:'Alex Jones'},
   {name:null}
 ]

if there are no numeric values in the names then a simple

_.sortBy(data, x => x.name)

or

_.orderBy(data, x => x.name) // since the default order is ["asc"]` 

would give you the result you want with the nulls being after the names.

However lets assume you have numeric values in the names for some reason:

 var data=[ {name:'John Alexov'}, {name:null}, {name:'Alex Jones'}, {name:null}, {name:null}, {name:'Mark 3rd'}, {name:'Bob Marley'}, {name:'john c'}, {name:'john 11th'}, {name:'john 1st'} ] var result = data.sort((x,y) => x.name && y.name ? x.name.localeCompare(y.name, undefined, {numeric: true}) : x.name ? -1 : y.name ? 1 : 0) console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Then you would need something like localeCompare(y.name, undefined, {numeric: true}) to make sure john 1st is above john 11th . localeCompare would also give you options when it comes to casing etc.

In vanilla js can do:

 data.sort((a,b)=>{ if(a.name===b.name){ return 0 }else if(a.name===null || b.name===null){ return a.name ? -1 : 1; } return a.name.localeCompare(b.name); }) console.log(data)
 <script> var data=[ {name:'F'}, {name:null}, {name:null}, {name:'A'} ] </script>

This solution worked for me and handles strings, number, booleans, and dates.

import { get, orderBy } from "lodash";

const items = [
  { id: 1, firstName: null, enabled: true, age: 30 },
  { id: 2, enabled: true, age: 31 },
  { id: 3, firstName: "", enabled: true, age: null },
  { id: 4, firstName: "A", enabled: false, age: undefined },
  { id: 5, firstName: "a", enabled: null, age: 10 },
  { id: 6, firstName: "b", enabled: undefined, age: 11 }
];

const sortIterate = (item, property) => {
  // Null will be returned for any undefined values
  const value = get(item, property, null);
  // If value is null set to empty string to get proper sort order
  // Works if comparing against strings, numbers, booleans, and dates.
  return value === null ? "" : value;
};

// Single sort example
const orderedArray = orderBy(
  items,
  [(item) => sortIterate(item, "firstName")],
  ["asc"]
);

// Multi sort example
const multiOrderedArray = orderBy(
  items,
  [
    (item) => sortIterate(item, "firstName"),
    (item) => sortIterate(item, "age")
  ],
  ["asc", "desc"]
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM