如何在JavaScript中对字符串排序

如何在JavaScript中对字符串排序,javascript,string,Javascript,String,我有一个对象列表,我希望根据string类型的字段attr进行排序。我尝试使用- list.sort(function (a, b) { return a.attr - b.attr }) 但是发现-在JavaScript中似乎不能处理字符串。如何根据字符串类型的属性对对象列表进行排序?根据您的示例使用: list.sort(function (a, b) { return ('' + a.attr).localeCompare(b.attr); }) 我们强制a.attr为

我有一个对象列表,我希望根据string类型的字段
attr
进行排序。我尝试使用
-

list.sort(function (a, b) {
    return a.attr - b.attr
})
但是发现
-
在JavaScript中似乎不能处理字符串。如何根据字符串类型的属性对对象列表进行排序?

根据您的示例使用:

list.sort(function (a, b) {
    return ('' + a.attr).localeCompare(b.attr);
})
我们强制a.attr为字符串以避免异常
localeCompare
已得到支持,Firefox 1。您还可能会看到使用的以下代码与区域设置无关:

if (item1.attr < item2.attr)
  return -1;
if ( item1.attr > item2.attr)
  return 1;
return 0;
if(item1.attritem2.attr)
返回1;
返回0;

您应该在此处使用>或
list.sort(function(item1, item2) {
    var val1 = item1.attr,
        val2 = item2.attr;
    if (val1 == val2) return 0;
    if (val1 > val2) return 1;
    if (val1 < val2) return -1;
});
list.sort(函数(item1,item2){
var val1=item1.attr,
val2=项目2.attr;
if(val1==val2)返回0;
如果(val1>val2)返回1;
if(val1
我已经为此烦恼了很长时间,所以我最终研究了这个问题,并给出了一个冗长的理由来解释为什么事情是这样的

从:

现在我们来看11.9.6

11.9.6   The Strict Equality Comparison Algorithm

The comparison x === y, where x and y are values, produces true or false. 
Such a comparison is performed as follows: 
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is Number, then
...
- If Type(x) is String, then return true if x and y are exactly the 
  same sequence of characters (same length and same characters in 
  corresponding positions); otherwise, return false.
就这样应用于字符串的三重等于运算符在参数完全相同的字符串(相同的长度和相应位置的相同字符)时返回true。

因此,
=
将在我们试图比较可能来自不同来源的字符串的情况下起作用,但我们知道这些字符串最终将具有相同的值-这对于代码中的内联字符串来说是一种非常常见的情况。例如,如果我们有一个名为
connection\u state
的变量,并且我们希望知道它现在处于以下哪个状态
['connecting'、'connected'、'disconnecting'、'disconnected']
,我们可以直接使用
===

但还有更多。在11.9.4的上方,有一个简短的注释:

NOTE 4     
  Comparison of Strings uses a simple equality test on sequences of code 
  unit values. There is no attempt to use the more complex, semantically oriented
  definitions of character or string equality and collating order defined in the 
  Unicode specification. Therefore Strings values that are canonically equal
  according to the Unicode standard could test as unequal. In effect this 
  algorithm assumes that both Strings are already in normalized form.
嗯,现在怎么办?外部获取的字符串可能是,也很可能是,怪异的unicodey,而我们温和的
==
不会公正地处理它们。在
localeCompare
中进行救援:

15.5.4.9   String.prototype.localeCompare (that)
    ...
    The actual return values are implementation-defined to permit implementers 
    to encode additional information in the value, but the function is required 
    to define a total ordering on all Strings and to return 0 when comparing
    Strings that are considered canonically equivalent by the Unicode standard. 
我们现在可以回家了

tl;博士


要比较javascript中的字符串,请使用
localeCompare
;如果您知道字符串没有非ASCII组件,因为它们是(例如)内部程序常量,那么
==
也可以工作。

在初始问题的操作中,您正在执行以下操作:

item1.attr - item2.attr
因此,假设这些都是数字(即item1.attr=“1”,item2.attr=“2”),只要确保类型正确,您仍然可以使用“==”运算符(或其他严格的计算器)。以下方面应起作用:

return parseInt(item1.attr) - parseInt(item2.attr);
如果是字母数字,请使用localCompare()。

更新的答案(2014年10月) 我对这个字符串自然排序顺序非常恼火,所以我花了相当长的时间来研究这个问题。我希望这有帮助

长话短说
localeCompare()。
正如Shog9所指出的,您的问题的答案是:

return item1.attr.localeCompare(item2.attr);
return item1.attr.localeCompare(item2.attr);
在所有自定义javascript“自然字符串排序顺序”实现中发现的bug 有相当多的自定义实现,试图更精确地进行字符串比较,称为“自然字符串排序顺序”

当“玩”这些实现时,我总是注意到一些奇怪的“自然排序顺序”选择,或者更确切地说是错误(或者在最好的情况下是遗漏)

通常,特殊字符(空格、破折号、符号和括号等)的处理不正确

然后,您会发现它们在不同的地方混合出现,通常可能是:

  • 有些将介于大写字母“Z”和小写字母“a”之间
  • 有些将介于“9”和大写字母“A”之间
  • 有些将在小写字母“z”之后
当人们期望特殊字符全部“分组”在一个地方时,除了空格特殊字符(可能总是第一个字符)。也就是说,要么全部在数字之前,要么全部在数字和字母之间(小写和大写字母一个接一个地“在一起”),要么全部在字母之后

我的结论是,当我开始添加几乎不常见的字符(即带变音符号的字符或破折号、感叹号等字符)时,它们都无法提供一致的顺序

关于自定义实现的研究:

  • Natural Compare Lite
    :排序一致失败,基本拉丁字符排序失败
  • 自然排序
    :排序一致失败,请参阅问题和基本拉丁字符排序
  • Javascript自然排序
    :自2012年2月以来似乎一直被忽视,排序一直失败,请参阅问题
  • Alphanum
    ,排序一致失败,请参阅
通过
localeCompare()
localeCompare()
IE6+支持最早的实现(没有locale和options参数),请参阅(向下滚动到localeCompare()方法)。 内置的
localeCompare()。
使用
localeCompare()
方法的唯一问题是

关于浏览器本机实现的研究:

  • -基本拉丁字符与localeCompare()的比较 -用于IE8测试的基本拉丁字符与localeCompare()的比较
  • -字符串比较中的基本拉丁字符:字符串与单独字符时的一致性检查
  • -IE11+支持新的区域设置和选项参数
“字符串自然排序顺序”的难度 实现一个可靠的算法(意思是:一致的,但也涵盖了广泛的字符)是一项非常艰巨的任务。UTF8包含&。 最后,还有一些规范f
return item1.attr.localeCompare(item2.attr);
list.sort(function(item1, item2){
    return +(item1.attr > item2.attr) || +(item1.attr === item2.attr) - 1;
}) 
+('aaa'>'bbb')||+('aaa'==='bbb')-1
+(false)||+(false)-1
0||0-1
-1

+('bbb'>'aaa')||+('bbb'==='aaa')-1
+(true)||+(false)-1
1||0-1
1

+('aaa'>'aaa')||+('aaa'==='aaa')-1
+(false)||+(true)-1
0||1-1
0
list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))
list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))
if (x == y) {
    return 0;
}
return x > y ? 1 : -1;
<!doctype html>
<html>
<body>
<p id = "myString">zyxtspqnmdba</p>
<p id = "orderedString"></p>
<script>
var myString = document.getElementById("myString").innerHTML;
orderString(myString);
function orderString(str) {
    var i = 0;
    var myArray = str.split("");
    while (i < str.length){
        var j = i + 1;
        while (j < str.length) {
            if (myArray[j] < myArray[i]){
                var temp = myArray[i];
                myArray[i] = myArray[j];
                myArray[j] = temp;
            }
            j++;
        }
        i++;
    }
    var newString = myArray.join("");
    document.getElementById("orderedString").innerHTML = newString;
}
</script>
</body>
</html>
(a,b) => (a < b ? -1 : a > b ? 1 : 0)
var str = ['v','a','da','c','k','l']
var b = str.join('').split('').sort().reverse().join('')
console.log(b)
list.sort(function (a, b) {
    return a.attr > b.attr ? 1: -1;
})