when we need to compare two objects a
and b
we also should test that one of them is not null
.
However, knowing that
>"a"==null false
>"a">null false
>"a"<null false
let arr = [
{ name: "a" },
{ name: null },
null,
{ name: "zaa" },
{ name: "dgh" }
];
let sortByName = function (a, b) {
if (a == null || b == null) return a - b;
if (a.name == null || b.name == null) return a.name - b.name;
return a.name.localeCompare(b.name);
};
console.log(arr.sort(sortByName));
the result is the following:
0: {name: 'a'}
1: {name: null}
2: null
3: {name: 'dgh'}
4: {name: 'zaa'}
how would you explain such a result?
CodePudding user response:
null - {} === NaN
{} - null === -0
Here:
if (a == null || b == null) return a - b;
You are subtracting anything from null
or null
from anything, if one of the 2 values is null
.
Replace null
with an empty string and use that in your comparison:
let arr = [
{ name: "a" },
{ name: null },
null,
{ name: "zaa" },
{ name: "dgh" }
];
let sortByName = function (a, b) {
return (a?.name ?? '').localeCompare(b?.name ?? '');
};
console.log(arr.sort(sortByName));
CodePudding user response:
If you want to make it so that null
comes before {name: null}
you can extend @Cerbrus answer to handle this.
A simple way to do this is convert both terms a
and b
into values that will in the end sort the way you like. I find the easiest way is to just prefix the input terms with another character you want to sort on.
eg.
If term is null, just return `0`;
If term is `{name:null}` return `1`;
Everything else just return `3` term;
It's kind of like creating a compound index..
Doing the above you can see it's very easy to make the sort do whatever you want based on certain conditions.. Eg, if you wanted null
to go to the end like undefined
simply change it's prefix, eg. make it 4
eg.
let arr = [
{ name: "a" },
{ name: null },
null,
{ name: "zaa" },
{ name: "dgh" }
];
function toStr(a) {
if (a === null) return '0';
else if (a.name === null) return '1';
else return '3' a.name;
}
let sortByName = function (a, b) {
return toStr(a).localeCompare(toStr(b));
};
console.log(arr.sort(sortByName));