如何在JavaScript中对字符串排序
本⽂翻译⾃:
I have a list of objects I wish to sort bad on a field attr of type string. 我有⼀个对象列表,希望根据字符串类型的字段
我有⼀个对象列表,希望根据字符串类型的字段attr进⾏我尝试使⽤-
排序。 I tried using - 我尝试使⽤
排序。
list.sort(function (a, b) {
return a.attr - b.attr
})
but found that - doesn't appear to work with strings in JavaScript. 但发现
在JavaScript中似乎不适⽤于字符串。 How can I
但发现-在JavaScript中似乎不适⽤于字符串。
sort a list of objects bad on an attribute with type string? 如何根据具有字符串类型的属性对对象列表进⾏排序?
如何根据具有字符串类型的属性对对象列表进⾏排序?
#1楼
#2楼
I had been bothered about this for long, so I finally rearched this and give you this long winded reason for why things are the way they are. 我已经为此烦恼了很长时间,所以我终于对此进⾏了研究,并为您提供了如此漫长的原因来说明事情的现状。
我已经为此烦恼了很长时间,所以我终于对此进⾏了研究,并为您提供了如此漫长的原因来说明事情的现状。From the : 从 :
从 :
Section 11.9.4 The Strict Equals Operator ( === )
The production EqualityExpression : EqualityExpression === RelationalExpression
is evaluated as follows:
- Let lref be the result of evaluating EqualityExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating RelationalExpression.
- Let rval be GetValue(rref).
- Return the result of performing the strict equality comparison
rval === lval. (See 11.9.6)
So now we go to 11.9.6 所以现在我们去11.9.6
所以现在我们去11.9.6
11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or fal.
Such a comparison is performed as follows:
- If Type(x) is different from Type(y), return fal.
- 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 quence of characters (same length and same characters in
corresponding positions); otherwi, return fal.
That's it. ⽽已。
⽽已。 The triple equals operator applied to strings returns true iff the arguments are exactly the same strings (same length and same characters in corresponding positions). 如果参数是完全相同的字符串(在相应位置具有相同的长度和相
如果参数是完全相同的字符串(在相应位置具有相同的长度和相同的字符),则应⽤于字符串的三元等于运算符将返回true。
So === will work in the cas when we're trying to compare strings which might have arrived from different sources, but which we know will eventually have the same values - a common enough scenario for inline strings in our code. 因此,当我们
因此,当我们尝试⽐较可能来⾃不同来源的字符串,但我们知道它们最终将具有相同的值时, ===将起作⽤。这是我们代码中内联字符串⾜够普遍的情况。
遍的情况。 For example, if we have a variable named connection_state , and we wish to know which one of the following states
例如,如果我们有⼀个名['connecting', 'connected', 'disconnecting', 'disconnected'] is it in right now, we can directly u the === . 例如,如果我们有⼀个名
显卡显存怎么看
为connection_state的变量,并且我们想知道现在处于以下哪个状态['connecting', 'connected', 'disconnecting', 'disconnected'] ,我们可以直接使⽤=== 。
But there's more. 但是还有更多。
在11.9.4之上,有⼀个简短的注释:
但是还有更多。 Just above 11.9.4, there is a short note: 在11.9.4之上,有⼀个简短的注释:
NOTE 4
Comparison of Strings us a simple equality test on quences of code
unit values. There is no attempt to u the more complex, mantically 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.
Hmm. 嗯嗯What now? 现在怎么办?
现在怎么办? Externally obtained strings can, and most likely will, be weird unicodey, and our gentle === won't do them justice. 外部获得的字符串可能⽽且很可能是奇怪的单⼀代码,⽽我们温和的
不会使它们公正。 In comes 外部获得的字符串可能⽽且很可能是奇怪的单⼀代码,⽽我们温和的===不会使它们公正。
在谈到localeCompare救援:
localeCompare to the rescue: 在谈到
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.
We can go home now. 我们现在可以回家了。
我们现在可以回家了。
tl;dr; tl; dr;
tl; dr;
To compare strings in javascript, u localeCompare ; 要⽐较javascript中的字符串,请使⽤
; if you know that
要⽐较javascript中的字符串,请使⽤localeCompare ;
the strings have no non-ASCII components becau they are, for example, internal program constants, then === also works.如果您知道字符串没有⾮ASCII成分,因为它们是例如内部程序常量,则===也可以。
#3楼
In your operation in your initial question, you are performing the following operation: 在初始问题中的操作中,您正在执⾏以下
在初始问题中的操作中,您正在执⾏以下操作:
item1.attr - item2.attr
So, assuming tho are numbers (ie item1.attr = "1", item2.attr = "2") You still may u the "===" operator (or other strict evaluators) provided that you ensure type. 因此,假设这些是数字(即item1.attr =“ 1”,item2.attr =“ 2”),只要确保
因此,假设这些是数字(即item1.attr =“ 1”,item2.attr =“ 2”),只要确保
以下应该⼯作:
输⼊类型,您仍然可以使⽤“ ===”运算符(或其他严格的求值器)。 The following should work: 以下应该⼯作:
输⼊类型,您仍然可以使⽤“ ===”运算符(或其他严格的求值器)。
return parInt(item1.attr) - parInt(item2.attr);
If they are alphaNumeric, then do u localCompare(). 如果它们是alphaNumeric,则请使⽤localCompare()。
如果它们是alphaNumeric,则请使⽤localCompare()。
地理教案#4楼
An updated answer (October 2014)更新的答案(2014年10⽉)
I was really annoyed about this string natural sorting order so I took quite some time to investigate this issue. 我对这种字符
我对这种字符
我希望这有帮助。
串⾃然排序顺序感到⾮常恼⽕,因此花了很多时间来研究这个问题。 I hope this helps. 我希望这有帮助。
串⾃然排序顺序感到⾮常恼⽕,因此花了很多时间来研究这个问题。
Long story short长话短说
localeCompare() character support is badass, just u it.localeCompare()字符⽀持很糟糕,只需使⽤它即可。
字符⽀持很糟糕,只需使⽤它即可。 As pointed out
by Shog9 , the answer to your question is: 正如
正如Shog9指出的Shog9 ,您的问题的答案是:
return item1.attr.localeCompare(item2.attr);
Bugs found in all the custom javascript "natural string sort order" implementations在所有⾃定义javascript“⾃然字符串排序顺序”实现中发现的错误
There are quite a bunch of custom implementations out there, trying to do string comparison more precily called "natural string sort order" 有很多⾃定义实现,试图更精确地进⾏字符串⽐较,称为“⾃然字符串排序顺序”
有很多⾃定义实现,试图更精确地进⾏字符串⽐较,称为“⾃然字符串排序顺序”
When "playing" with the implementations, I always noticed some strange "natural sorting order" choice, or rather mistakes (or omissions in the best cas). 当“尝试”这些实现时,我总是注意到⼀些奇怪的“⾃然排序顺序”选择,或者是错误(或者在
当“尝试”这些实现时,我总是注意到⼀些奇怪的“⾃然排序顺序”选择,或者是错误(或者在最佳情况下是遗漏)。
Typically, special characters (space, dash, ampersand, brackets, and so on) are not procesd correctly. 通常,特殊字符(空
通常,特殊字符(空格,破折号,“&”号,⽅括号等)未正确处理。
You will then find them appearing mixed up in different places, typically that could be: 然后,您会发现它们在不同的位置混合
然后,您会发现它们在不同的位置混合出现,通常可能是:
some will be between the upperca 'Z' and the lowerca 'a' 有些会在⼤写字母“ Z”和⼩写字母“ a”之间形容震撼的成语
有些会在⼤写字母“ Z”和⼩写字母“ a”之间some will be between the '9' and the upperca 'A' 有些会在'9'和⼤写字母'A'之间
有些会在'9'和⼤写字母'A'之间
some will be after lowerca 'z' 有些将在⼩写字母“ z”之后
有些将在⼩写字母“ z”之后
When one would have expected special characters to all be "grouped" together in one place, except for the space special character maybe (which would always be the first character). 当⼀个⼈希望所有特殊字符都被“分组”在⼀个地⽅时,除了空格
当⼀个⼈希望所有特殊字符都被“分组”在⼀个地⽅时,除了空格特殊字符(总是第⼀个字符)。 That is, either all before numbers, or all between numbers and letters (lowerca & upperca 特殊字符(总是第⼀个字符)。
being "together" one after another), or all after letters. 也就是说,要么全部在数字之前,要么全部在数字和字母之间(⼩写字母
也就是说,要么全部在数字之前,要么全部在数字和字母之间(⼩写字母和⼤写字母彼此“在⼀起”),或者全部在字母之后。
My conclusion is that they all fail to provide a consistent order when I start adding barely unusual characters (ie. characters with diacritics or charcters such as dash, exclamation mark and so on). 我的结论是,当我开始添加⼏乎不寻常的字符(即带有
我的结论是,当我开始添加⼏乎不寻常的字符(即带有变⾳符号或字符(例如破折号,感叹号等)的字符时,它们都⽆法提供⼀致的顺序。
Rearch on the custom implementations: 有关⾃定义实现的研究:
有关⾃定义实现的研究:
Natural Compare Lite : Fails at sorting consistently and , basic latin characters sorting Natural Compare Lite:⽆法始终如⼀地排序和 ,基本拉丁字符排序
Natural Sort : Fails at sorting consistently, e issue and e basic latin characters sorting Natural Sort:未能始终进⾏排序,请参见问题并查看基本的拉丁字符排序
Javascript Natural Sort : ems rather neglected since February 2012, Fails at sorting consistently, e issue Javascript Natural Sort:⾃2012年2⽉以来似乎已被忽略,未能始终如⼀地排序,请参见问题
Alphanum , Fails at sorting consistently, e Alphanum,⽆法始终如⼀地排序,请参见 ,
Browrs' native "natural string sort order" implementations via localeCompare()浏览器通过localeCompare()的本机“⾃然字符串排序顺序”实现
Rearch on the browr-native implementations: 对浏览器本地实现的研究:
对浏览器本地实现的研究:
- basic latin characters comparison with localeCompare() - basic latin characters comparison with localeCompare() for
testing on IE8 与localeCompare()的基本拉丁字符⽐较与localeCompare()的基本拉丁字符⽐较⽤于测试IE8与localeCompare()的基本拉丁字符⽐较与localeCompare()的基本拉丁字符⽐较⽤于测试IE8 - basic latin characters in string comparison : consistency check in string vs when a character is alone 字符串⽐较中的基
字符串⽐较中的基本拉丁字符:字符串中的⼀致性检查与单独使⽤字符时
- IE11+ supports the new locales & options arguments +⽀持新的语⾔环境和选项参数
+⽀持新的语⾔环境和选项参数
Difficulty of "string natural sorting order" “字符串⾃然排序顺序”的困难
Final conclusion定论
So considering the current level of support provided by the javascript custom implementations I came across, we will probably never e anything getting any clo to supporting all this characters & scripts (languages). 因此,考虑到我遇到的
cur
因此,考虑到我遇到的javascript⾃定义实现所提供的当前⽀持⽔平,我们可能永远不会看到有什么东西能够接近⽀持所有这些字符和脚本(语⾔)的。Hence I would rather u the browrs' native localeCompare() method. 因此,我宁愿使⽤浏览器的本地localeCompare()
因此,我宁愿使⽤浏览器的本地localeCompare()⽅法。 Yes, it does have the downside of beeing non-consistent across browrs but basic testing shows it covers a much ⽅法。
wider range of characters, allowing solid & meaningful sort orders. 是的,它确实存在跨浏览器不⼀致的缺点,但是基本测试表
是的,它确实存在跨浏览器不⼀致的缺点,但是基本测试表明,它涵盖了更⼤范围的字符,允许可靠且有意义的排序顺序。
So as pointed out by Shog9 , the answer to your question is: 因此,正如
因此,正如Shog9所指出的,您的问题的答案是:
return item1.attr.localeCompare(item2.attr);
Further reading:进⼀步阅读:
Thanks to Shog9's nice answer, which put me in the "right" direction I believe 多亏Shog9的好回答,我相信我朝着“正确”的
多亏Shog9的好回答,我相信我朝着“正确”的⽅向前进
#5楼
list.sort(function(item1, item2){
return +(item1.attr > item2.attr) || +(item1.attr === item2.attr) - 1;
})
阳痿吃什么好
How they work samples: 它们是如何⼯作的:
它们是如何⼯作的:
+('aaa'>'bbb')||+('aaa'==='bbb')-1
+(fal)||+(fal)-1
0||0-1
-1
+('bbb'>'aaa')||+('bbb'==='aaa')-1
+(true)||+(fal)-1
1||0-1
1
+('aaa'>'aaa')||+('aaa'==='aaa')-1
+(fal)||+(true)-1
0||1-1
#6楼
Answer (in Modern ECMAScript)答案(现代ECMAScript中)
list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))
Or 要么
要么
list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))
Description描述
Casting a boolean value to a number yields the following: 将布尔值转换为数字会产⽣以下结果:
将布尔值转换为数字会产⽣以下结果:
true -> 1true -> 1
fal -> 0fal -> 0
Consider three possible patterns: 考虑三种可能的模式:
考虑三种可能的模式:
x is larger than y: (x > y) - (y < x) -> 1 - 0 -> 1 x⼤于y:
x⼤于y: (x > y) - (y < x) -> 1 - 0 > 1
x is equal to y: (x > y) - (y < x) -> 0 - 0 -> 0 x等于y:
x等于y: (x > y) - (y < x) -> 0 - 0 > 0
x is smaller than y: (x > y) - (y < x) -> 0 - 1 -> -1 x⼩于y:
x⼩于y: (x > y) - (y < x) -> 0 - 1 > -1
(Alternative) (可选)
(可选)
x is larger than y: +(x > y) || -(x < y) x⼤于y:
x⼤于y: +(x > y) || -(x < y)+(x > y) || -(x < y) -> 1 || 0+(x > y) || -(x < y) -> 1 || 01 || 0 -> 11 || 0 > 1
x is equal to y: +(x > y) || -(x < y) x等于y:
x等于y: +(x > y) || -(x < y)+(x > y) || -(x < y) -> 0 || 0+(x > y) || -(x < y) -> 0 || 00 || 0 -> 00 || 0 > 0 x is smaller than y: +(x > y) || -(x < y) x⼩于y:
x⼩于y: +(x > y) || -(x < y)+(x > y) || -(x < y) -> 0 || -1+(x > y) || -(x < y) -> 0 || -10 || -1 -> -10 || -1 > -1
So the logics are equivalent to typical sort comparator functions. 因此,这些逻辑等效于典型的排序⽐较器功能。
因此,这些逻辑等效于典型的排序⽐较器功能。
if (x == y) {
美食做法视频return 0;
读后感20字
}
阳春面做法
return x > y ? 1 : -1;