javascript 如何比较字符串和数值(尊重负值,空值总是最后)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19101573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can one compare string and numeric values (respecting negative values, with null always last)?
提问by lebolo
I'm trying to sort an array of values that can be a mixture of numeric or string values (e.g. [10,"20",null,"1","bar","-2",-3,null,5,"foo"]
). How can I sort this array such that
我正在尝试对可以是数字或字符串值(例如[10,"20",null,"1","bar","-2",-3,null,5,"foo"]
)的混合值的数组进行排序。我怎样才能对这个数组进行排序,使得
null
values are always placed last (regardless of sorting order, see jsFiddle)- negative numbers are sorted correctly (i.e. they are less than positive numbers and sort correctly amongst themselves)
null
值总是放在最后(无论排序顺序如何,请参阅 jsFiddle)- 负数排序正确(即它们小于正数并在它们之间正确排序)
? I made a jsFiddlewith detailed numeric and string examples (using localeCompare
and the numeric
option), but will paste the numeric version of my sorting algorithm below as a starting point.
? 我制作了一个带有详细数字和字符串示例(使用和选项)的jsFiddle,但将在下面粘贴我的排序算法的数字版本作为起点。localeCompare
numeric
// Sorting order
var order = "asc"; // Try switching between "asc" and "dsc"
// Dummy arrays
var numericArr = [10,20,null,1,-2,-3,null,5];
// Sort arrays
$(".output1").append(numericArr.toString());
numericArr.sort(sortByDataNumeric);
$(".output2").append(numericArr.toString());
// Numeric sorting function
function sortByDataNumeric(a, b, _order) {
// Replace internal parameters if not used
if (_order == null) _order = order;
// If values are null, place them at the end
var dflt = (_order == "asc" ? Number.MAX_VALUE : -Number.MAX_VALUE);
// Numeric values
var aVal = (a == null ? dflt : a);
var bVal = (b == null ? dflt : b);
return _order == "asc" ? (aVal - bVal) : (bVal - aVal);
}
The problem with my string sorting algorithm (see jsFiddle) is that I can't find a way to always place null
values last and negative values aren't correctly sorted within themselves (e.g. -3 should be less than -2)
我的字符串排序算法(请参阅jsFiddle)的问题是我无法找到一种方法将null
值始终放在最后,并且负值本身没有正确排序(例如 -3 应该小于 -2)
Edit
编辑
To answer the comments, I expect [10,"20",null,"1","bar","-2",-3,null,5,"foo"]
to sort to [-3,"-2","1",5,10,"20","bar","foo",null,null]
为了回答评论,我希望[10,"20",null,"1","bar","-2",-3,null,5,"foo"]
排序[-3,"-2","1",5,10,"20","bar","foo",null,null]
回答by thgaskell
You should first check to see if either value is null
and return the opposite value.
您应该首先检查是否有任何一个值null
并返回相反的值。
On a side note:
附带说明:
For your default _order
value, you should check if the parameter is undefined
instead of comparing its value to null
. If you try to compare something that is undefined directly you will get a reference error:
对于默认_order
值,您应该检查参数是否为 ,undefined
而不是将其值与null
. 如果您尝试直接比较未定义的内容,您将收到参考错误:
(undefinedVar == null) // ReferenceError: undefinedVar is not defined
Instead, you should check if the variable is undefined:
相反,您应该检查变量是否未定义:
(typeof undefinedVar == "undefined") // true
Also, it's probably a better idea to wrap your compare function in a closure instead of relying on a global order variable.
此外,将比较函数包装在闭包中而不是依赖全局顺序变量可能是一个更好的主意。
Sometime like:
有时像:
[].sort(function(a, b){ return sort(a, b, order)})
This way you can sort at a per-instance level.
通过这种方式,您可以在每个实例级别进行排序。
JavaScript
JavaScript
function sort(a, b, asc) {
var result;
/* Default ascending order */
if (typeof asc == "undefined") asc = true;
if (a === null) return 1;
if (b === null) return -1;
if (a === null && b === null) return 0;
result = a - b;
if (isNaN(result)) {
return (asc) ? a.toString().localeCompare(b) : b.toString().localeCompare(a);
}
else {
return (asc) ? result : -result;
}
}
回答by andi
function sortByDataString(a, b) {
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
if (isNumber(a) && isNumber(b)) {
if (parseInt(a,10) === parseInt(b,10)) {
return 0;
}
return parseInt(a,10) > parseInt(b,10) ? 1 : -1;
}
if (isNumber(a)) {
return -1;
}
if (isNumber(b)) {
return 1;
}
if (a === b) {
return 0;
}
return a > b ? 1 : -1;
}
fiddle here: http://jsfiddle.net/gxFGN/6/
在这里小提琴:http: //jsfiddle.net/gxFGN/6/
I left out the order parameter, but you could always reverse the array at the end if needed.
我省略了 order 参数,但如果需要,您始终可以在最后反转数组。
回答by Bergi
Use this:
用这个:
function typeOrder(x) {
if (x == null)
return 2;
if (isNaN(+x))
return 1;
return 0;
}
function sortNumber(a, b) {
a = parseInt(a, 10); b = parseInt(b, 10);
if (isNaN(a) || isNaN(b))
return 0;
return a - b;
}
function sortString(a, b) {
if (typeof a != "string" || typeof b != "string")
return 0;
return +(a > b) || -(b > a);
}
order = order == "dsc" ? -1 : 1;
numericArr.sort(function(a, b) {
return order * ( typeOrder(a)-typeOrder(b)
|| sortNumber(a, b)
|| sortString(a, b)
);
});
(更新小提琴)
回答by Yevgeny Simkin
I'm pretty sure that your problem is a red herring... the abstract function that you past into sort
doesn't get a third parameter (in your case _order
). So in your situation that's always going to be undefined
.
我很确定你的问题是一个红鲱鱼......你过去的抽象函数sort
没有得到第三个参数(在你的情况下_order
)。所以在你的情况下,总是会undefined
。
Please reconsider your code with that in mind and see what you get.
请考虑到这一点重新考虑您的代码,看看您会得到什么。
The array you specify is entirely Numeric so your sort should work correctly, though as other commenters have suggested, if your array ever winds up with string values (i.e. "10", "-7" etc) you'll want to parseInt and test for isNaN before doing your comparison.
您指定的数组完全是数字,因此您的排序应该正常工作,尽管正如其他评论者所建议的那样,如果您的数组以字符串值(即“10”、“-7”等)结束,您将需要 parseInt 并测试在进行比较之前为 isNaN 。