attr
文字列型のフィールドに基づいてソートしたいオブジェクトのリストがあります。使ってみた-
list.sort(function (a, b) {
return a.attr - b.attr
})
しかし-
、JavaScriptの文字列では動作しないようです。文字列型の属性に基づいてオブジェクトのリストをソートするにはどうすればよいですか?
Javascript : remove accents/diacritics in strings
attr
文字列型のフィールドに基づいてソートしたいオブジェクトのリストがあります。使ってみた-
list.sort(function (a, b) {
return a.attr - b.attr
})
しかし-
、JavaScriptの文字列では動作しないようです。文字列型の属性に基づいてオブジェクトのリストをソートするにはどうすればよいですか?
Javascript : remove accents/diacritics in strings
回答:
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;
localeCompare()
この問題は発生しませんが、数値を理解できないため、ほとんどの言語でのソート比較と同様に、["1"、 "10"、 "2"]が得られます。alphanum /自然ソートアルゴリズムにあなたのUIのフロントエンドのために並べ替えたい場合は、ルックstackoverflow.com/questions/4340227/...またはstackoverflow.com/questions/4321829/...
localeCompare()
多くのバージョンの遡りをサポートしていますが、バージョン11までのロケールの指定をサポートしていません。Dead.Rabitがリンクしている質問にも注意してください。
この文字列の自然なソート順に本当に悩まされていたので、この問題を調査するためにかなりの時間をかけました。これがお役に立てば幸いです。
localeCompare()
キャラクターサポートは悪いです、それを使ってください。が指摘したようShog9
に、あなたの質問に対する答えは次のとおりです。
return item1.attr.localeCompare(item2.attr);
かなりたくさんのカスタム実装があり、より正確に「自然な文字列のソート順」と呼ばれる文字列比較を行おうとしています
これらの実装で「遊ぶ」とき、私はいつも奇妙な「自然なソート順」の選択、またはむしろ間違い(または最良の場合は省略)に気づきました。
通常、特殊文字(スペース、ダッシュ、アンパサンド、角かっこなど)は正しく処理されません。
次に、それらがさまざまな場所で混ざって表示されるのを見つけます。
スペースの特殊文字(常に最初の文字)を除いて、すべての特殊文字が1つの場所に「グループ化」されることが期待される場合。つまり、数字の前すべて、または数字と文字の間のすべて(小文字と大文字が次々に「一緒に」)、またはすべて文字の後。
私の結論は、かろうじて珍しい文字(つまり、発音記号やダッシュ、感嘆符などの文字を含む文字)を追加し始めると、すべてが一貫した順序を提供できないということです。
カスタム実装に関する調査:
Natural Compare Lite
https://github.com/litejs/natural-compare-lite:常にソートに失敗するhttps://github.com/litejs/natural-compare-lite/issues/1およびhttp://jsbin.com/bevututodavi/ 1 / edit?js、console、基本的なラテン文字の並べ替えhttp://jsbin.com/bevututodavi/5/edit?js,console Natural Sort
https://github.com/javve/natural-sort:、常にソートに失敗する問題を参照してくださいhttps://github.com/javve/natural-sort/issues/7およびソート基本ラテン文字参照にhttp:// jsbin。 com / cipimosedoqe / 3 / edit?js、コンソール Javascript Natural Sort
https://github.com/overset/javascript-natural-sort:2012年 2月以降は無視されているようです。ソートに一貫して失敗します。https://github.com/overset/javascript-natural-sort/issues/16を参照してくださいAlphanum
http://www.davekoelle.com/files/alphanum.js、一貫仕分けで失敗し、参照http://jsbin.com/tuminoxifuyo/1/edit?js,consolelocaleCompare()
localeCompare()
(ロケールとオプション引数なし)最古の実装は、IE6 +によってサポートされている、参照http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx((localeCompareまでスクロールし) 方法)。組み込みのlocaleCompare()
方法では、国際文字や特殊文字を含めて、並べ替えの作業が大幅に改善されます。このlocaleCompare()
メソッドを使用する唯一の問題は、「使用されるロケールとソート順は完全に実装に依存する」ということです。つまり、stringOne.localeCompare(stringTwo)などのlocaleCompareを使用する場合、Firefox、Safari、Chrome、IEでは文字列の並べ替え順序が異なります。
ブラウザネイティブ実装に関する調査:
堅固なアルゴリズム(つまり、一貫しているが幅広い文字をカバーする)を実装することは、非常に困難な作業です。UTF8が含まれ、2000の以上の文字&カバー120の以上のスクリプト(言語)。最後に、このタスクにはいくつかの仕様があります。これは「Unicode照合アルゴリズム」と呼ばれ、http://www.unicode.org/reports/tr10/にあります。あなたは私が投稿したこの質問でこれに関する詳細情報を見つけることができます/software/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order
したがって、私が遭遇したjavascriptカスタム実装によって提供される現在のレベルのサポートを考えると、このすべての文字とスクリプト(言語)のサポートに近づくことはないでしょう。したがって、ブラウザのネイティブのlocaleCompare()メソッドを使用する方がよいでしょう。はい、ブラウザ間で一貫性がないという欠点がありますが、基本的なテストでは、はるかに広い範囲の文字をカバーしているため、確実で意味のある並べ替え順序が可能です。
で指摘されているようShog9
に、あなたの質問への答えは:
return item1.attr.localeCompare(item2.attr);
Shog9の良い答えのおかげで、私は「正しい」方向に私を信じました
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) - (y < x)
-> 1 - 0
->1
(x > y) - (y < x)
-> 0 - 0
->0
(x > y) - (y < x)
-> 0 - 1
->-1
(代替)
+(x > y) || -(x < y)
-> 1 || 0
->1
+(x > y) || -(x < y)
-> 0 || 0
->0
+(x > y) || -(x < y)
-> 0 || -1
->-1
したがって、これらのロジックは、典型的なソートコンパレーター関数と同等です。
if (x == y) {
return 0;
}
return x > y ? 1 : -1;
localeCompare
と標準比較では異なる結果が得られます。あなたはどちらを期待していますか? ["A", "b", "C", "d"].sort((a, b) => a.localeCompare(b))
大文字と小文字を区別しないアルファベット順に並べ替え、["A", "b", "C", "d"].sort((a, b) => (a > b) - (a < b))
コードポイント順に並べ替え
ここでは>または<および==を使用する必要があります。したがって、解決策は次のようになります。
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;
});
文字列はJavaScriptで直接比較できるので、これは仕事をします
list.sort(function (a, b) {
return a.attr > b.attr ? 1: -1;
})
ソート関数の減算は、非アルファベット(数値)ソートが必要な場合にのみ使用され、もちろん文字列では機能しません
私は長い間これに悩まされていたので、私はついにこれを調査し、物事がそれらの方法である理由のこの長い風の理由をあなたに与えます。
スペックから:
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コンポーネントがないことがわかっている場合は、これ===
も機能します。
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
<!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>
JavaScript case insensitive string comparison
してください