admin管理员组文章数量:1133769
I need to sort an array of strings, but I need it so that null is always last. For example, the array:
var arr = [a, b, null, d, null]
When sorted ascending I need it to be sorted like [a, b, d, null, null]
and when sorted descending I need it to be sorted like [d, b, a, null, null]
.
Is this possible? I tried the solution found below but it's not quite what I need.
How can one compare string and numeric values (respecting negative values, with null always last)?
I need to sort an array of strings, but I need it so that null is always last. For example, the array:
var arr = [a, b, null, d, null]
When sorted ascending I need it to be sorted like [a, b, d, null, null]
and when sorted descending I need it to be sorted like [d, b, a, null, null]
.
Is this possible? I tried the solution found below but it's not quite what I need.
How can one compare string and numeric values (respecting negative values, with null always last)?
Share Improve this question edited May 23, 2017 at 11:54 CommunityBot 11 silver badge asked Apr 23, 2015 at 16:21 SirkSirk 1,5972 gold badges12 silver badges18 bronze badges 1- Use your own custom sort function a la stackoverflow.com/q/8537602/438992 that always returns greater-than for nulls. – Dave Newton Commented Apr 23, 2015 at 16:24
9 Answers
Reset to default 239Check out .sort()
and do it with custom sorting.
Example
function alphabetically(ascending) {
return function (a, b) {
// equal items sort equally
if (a === b) {
return 0;
}
// nulls sort after anything else
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
// otherwise, if we're ascending, lowest sorts first
if (ascending) {
return a < b ? -1 : 1;
}
// if descending, highest sorts first
return a < b ? 1 : -1;
};
}
var arr = [null, "a", "z", null, "b"];
console.log(arr.sort(alphabetically(true)));
console.log(arr.sort(alphabetically(false)));
Use a custom compare function that discriminates against null
values:
arr.sort(function(a, b) {
return (a===null)-(b===null) || +(a>b)||-(a<b);
});
For descending order of the non-null values, just swap a
and b
in the direct comparison:
arr.sort(function(a, b) {
return (a===null)-(b===null) || -(a>b)||+(a<b);
});
Ascending
arr.sort((a, b) => (a != null ? a : Infinity) - (b != null ? b : Infinity))
Descending
arr.sort((a, b) => (b != null ? b : -Infinity) - (a != null ? a : -Infinity))
(For descending order if you don't have negative values in the array, I recommend to use 0 instead of -Infinity)
The simplest approach is to handle null
first, then deal with non-null cases based on the desired order:
function sortnull(arr, ascending) {
// default to ascending
if (typeof(ascending) === "undefined")
ascending = true;
const multiplier = ascending ? 1 : -1;
const sorter = function(a, b) {
if (a === b) // identical? return 0
return 0;
else if (a === null) // a is null? last
return 1;
else if (b === null) // b is null? last
return -1;
else // compare, negate if descending
return a.localeCompare(b) * multiplier;
}
return arr.sort(sorter);
}
const arr = ["a", "b", null, "d", null];
console.log(sortnull(arr)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, true)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, false)); // descending ["d", "b", "a", null, null]
If you need natural sorting for numbers, or any of the options provided by Collator
(including speed enhancements and respecting locale), try this approach, based off of Paul Roub's solution, cleaned up a bit. We almost always use numeric sorting, hence the defaults...
If you are not a Typescript fan, just strip off the :type
specs or copy from the snippet.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator
const naturalCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
const alphabeticCollator = new Intl.Collator(undefined, {});
function nullSort(descending: boolean = false, alphabetic: boolean = false) {
return function (a: any, b: any): number {
if (a === b) {
return 0;
}
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
let ret
if (alphabetic) {
ret = alphabeticCollator.compare(a, b)
} else {
ret = naturalCollator.compare(a, b)
}
if (descending) {
ret = -ret
}
return ret
};
}
Use it like this.
// numeric, ascending (default)
myList.sort(nullSort());
// alphabetic, descending
myList.sort(nullSort(true, true));
You can modify the factory method to take a collator instead, for greater flexibility.
function nullSort(descending: boolean = false, collator: Collator = naturalCollator)
Working Snippet
const naturalCollator = new Intl.Collator(undefined, {
numeric: true,
sensitivity: 'base'
});
const alphabeticCollator = new Intl.Collator(undefined, {});
function nullSort(descending = false, alphabetic = false) {
return function(a, b) {
if (a === b) {
return 0;
}
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
let ret
if (alphabetic) {
ret = alphabeticCollator.compare(a, b)
} else {
ret = naturalCollator.compare(a, b)
}
if (descending) {
ret = -ret
}
return ret
};
}
const items = [null, 10, 1, 100, null, 'hello', .1, null]
console.log(items.sort(nullSort()));
I implemented a custom sort function for an Ant Design table that handles dates, including scenarios where date values might be null or empty. This approach ensures a consistent sorting order, placing null or empty values at the end of the list, regardless of the sort direction. The function makes use of the localeCompare method for string comparison, which is useful for date strings in ISO format. Here's the code snippet:
compare: (a, b, sortDirection) => {
const aa = a.StartsOn || "";
const bb = b.StartsOn || "";
// Check if both are empty or null
if (!aa && !bb) return 0;
// Ensure empty or null values always go last in both directions
if (!aa) return 1; // aa is empty or null, it goes last
if (!bb) return -1; // bb is empty or null, it goes last
// Ascending order comparison
if (sortDirection === "ascend") {
return aa.localeCompare(bb);
}
// Descending order comparison
else if (sortDirection === "descend") {
return bb.localeCompare(aa);
}
},
This solution simplifies the sorting logic by explicitly handling the sort direction (ascend or descend) and null or empty values. In my experience, incorporating the sort direction directly into the comparison logic makes the sorter more intuitive and straightforward, avoiding unnecessary complexity for what should be a simple problem.
I am sorting objects with a custom index and this works for me. I am not wanting to change the original array and it is important to keep the null indexes where they are.
let sorted = [...array].sort((a, b) => {
if (!a || !b) return 0;
else return a.CustomIndex - b.CustomIndex;
});
My solution is to convert null to "" when doing comparison:
array.sort((a, b) => (a === null ? '' : a) - (b===null ? '': b))
Do it like:
var arr = [a, b, null, d, null]
foreach ($arr as $key => $value) {
if($value == null)
unset($arr[$key]);
$arr[] = $value;
}
// rebuild array index
$arr = array_values($arr);
echo '<pre>';print_r($arr);die;
本文标签: javascriptSort an array so that null values always come lastStack Overflow
版权声明:本文标题:javascript - Sort an array so that null values always come last - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736771633a1952116.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论