我有一个对象列表,我希望基于类型字符串的字段attr进行排序。我试着用
list.sort(function (a, b) {
return a.attr - b.attr
})
但发现-似乎不适用于JavaScript中的字符串。我如何能排序基于类型字符串的属性的对象列表?
我有一个对象列表,我希望基于类型字符串的字段attr进行排序。我试着用
list.sort(function (a, b) {
return a.attr - b.attr
})
但发现-似乎不适用于JavaScript中的字符串。我如何能排序基于类型字符串的属性的对象列表?
当前回答
为什么问题中的方法不起作用的解释:
let products = [
{ name: "laptop", price: 800 },
{ name: "phone", price:200},
{ name: "tv", price: 1200}
];
products.sort( (a, b) => {
{let value= a.name - b.name; console.log(value); return value}
});
> 2 NaN
字符串之间的减法返回NaN。
附和@Alejadro的回答,正确的方法是——
产品。排序(a,b) => a。一、二、三)
其他回答
直接使用sort(),不带任何-或<
Const区域=['山','海滩','沙漠','山'] console.log (areas.sort ()) //以降序方式打印 .reverse console.log (areas.sort () ())
答案(现代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))
描述
将一个布尔值转换为一个数字会产生以下结果:
True -> 1 .单击“确定” False -> 0
考虑三种可能的模式:
X大于y: (X > y) - (y < X) -> 1 - 0 -> 1 X等于y:(X > y) - (y < X) -> 0 - 0 -> 0 X小于y:(X > y) - (y < X) -> 0 -1 -> -1
(替代)
x比y: + (x > y) | | - - - - - - (x < y) - > 1 | | 0 - > 1 x等于y: + (x > y) | | - - - - - - (x < y) - > 0 | | 0 - > 0 x小于y: + (x > y) | | - - - - - - (x < y) - > 0 | | 1 - > 1
这些逻辑等价于典型的排序比较器函数。
if (x == y) {
return 0;
}
return x > y ? 1 : -1;
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
我为这个问题困扰了很久,所以我最终研究了这个问题,并给了你一个冗长的原因,为什么事情是这样的。
来自规范:
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)
现在我们看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_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.
嗯。现在该做什么?外部获得的字符串可能,而且很可能会是奇怪的统一码,而我们温和的===不会公正地对待它们。在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; diana;
要比较javascript中的字符串,请使用localeCompare;如果您知道字符串没有非ascii组件,因为它们是,例如,内部程序常量,那么===也适用。
按照你的例子使用String.prototype.localeCompare:
list.sort(function (a, b) {
return ('' + a.attr).localeCompare(b.attr);
})
我们强制a.attr为字符串以避免异常。从Internet Explorer 6和Firefox 1开始就支持localeCompare。你可能还会看到下面的代码不尊重区域设置:
if (item1.attr < item2.attr)
return -1;
if ( item1.attr > item2.attr)
return 1;
return 0;