462

文字列型のフィールドに基づいて並べ替えたいオブジェクトのリストがありますattr。使ってみた-

list.sort(function (a, b) {
    return a.attr - b.attr
})

しかし-、JavaScript の文字列では機能しないようです。文字列型の属性に基づいてオブジェクトのリストをソートするにはどうすればよいですか?

4

16 に答える 16

814

例ごとに使用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;
于 2008-09-09T03:29:17.300 に答える
68

回答 (最新の ECMAScript で)

list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))

または

list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))

説明

ブール値を数値にキャストすると、次のようになります。

  • true->1
  • false->0

考えられる 3 つのパターンを考えてみましょう。

  • 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;
于 2016-11-01T06:28:02.517 に答える
14

ここでは > または < と == を使用する必要があります。したがって、解決策は次のようになります。

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;
});
于 2008-09-09T03:29:42.930 に答える
7

私はこれについて長い間悩まされていたので、最終的にこれを調査し、物事がこのようになっている理由について、この長く曲がりくねった理由を説明します。

仕様から:

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;dr;

JavaScript で文字列を比較するには、localeCompare;を使用します。たとえば、文字列が内部プログラム定数であるため、文字列に非ASCIIコンポーネントがないことがわかっている場合===も機能します。

于 2013-02-07T18:06:20.243 に答える
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
于 2016-09-01T21:41:22.050 に答える
0

最初の質問での操作では、次の操作を実行しています。

item1.attr - item2.attr

したがって、それらが数値であると仮定すると (つまり、item1.attr = "1"、item2.attr = "2")、型が保証されていれば、"===" 演算子 (または他の厳密な評価子) を引き続き使用できます。以下が機能するはずです。

return parseInt(item1.attr) - parseInt(item2.attr);

alphaNumeric の場合は、localCompare() を使用してください。

于 2013-10-24T18:15:33.813 に答える
0

-orなしで直接 sort() を使用します<

const areas = ['hill', 'beach', 'desert', 'mountain']
console.log(areas.sort())

// To print in descending way
console.log(areas.sort().reverse())

于 2021-01-31T12:32:54.937 に答える