JavaScriptで並べ替える必要がある文字列の配列がありますが、大文字と小文字を区別しません。これを実行するには?
(ほぼ:)ワンライナー
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
結果として
[ 'bar', 'Foo' ]
ながら
["Foo", "bar"].sort();
結果として
[ 'Foo', 'bar' ]
myArray.sort(
function(a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1;
if (a.toLowerCase() > b.toLowerCase()) return 1;
return 0;
}
);
編集:パフォーマンスを念頭に置いているのではなく、このテクニックを説明するために最初に書いたことに注意してください。よりコンパクトなソリューションについては、@ Ivan Krechetovの回答も参照してください。
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a == b) return 0;
if (a > b) return 1;
return -1;
});
この古い質問を再検討する時が来ました。
toLowerCase
に依存するソリューションを使用しないでください。それらは非効率的であり、一部の言語(トルコ語では単に動作しない例えば)。これを好む:
['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))
ブラウザの互換性について documentation を確認してください。また、sensitivity
オプションについて知っていることはすべてあります。
入力配列の要素の順序に関係なく同じ順序を保証したい場合は、 stable 並べ替えがあります。
myArray.sort(function(a, b) {
/* Storing case insensitive comparison */
var comparison = a.toLowerCase().localeCompare(b.toLowerCase());
/* If strings are equal in case insensitive comparison */
if (comparison === 0) {
/* Return case sensitive comparison instead */
return a.localeCompare(b);
}
/* Otherwise return result */
return comparison;
});
新しい Intl.Collator().compare
を使用することもできます。MDNごとに、配列をソートするときに より効率的 です。欠点は、古いブラウザではサポートされていないことです。 MDNは、Safariではまったくサポートされていないと述べています。 Intl.Collator
がサポートされていると記載されているため、検証する必要があります。
大きな配列の並べ替えなど、多数の文字列を比較する場合は、Intl.Collatorオブジェクトを作成し、compareプロパティで提供される関数を使用することをお勧めします
["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
.sort()
のケースを.toLowerCase()
で正規化します。
他の答えは、配列に文字列が含まれていることを前提としています。配列にnull、未定義、またはその他の非文字列が含まれている場合でも機能するため、私の方法の方が優れています。
var notdefined;
var myarray = ['a', 'c', null, notdefined, 'nulk', 'BYE', 'nulm'];
myarray.sort(ignoreCase);
alert(JSON.stringify(myarray)); // show the result
function ignoreCase(a,b) {
return (''+a).toUpperCase() < (''+b).toUpperCase() ? -1 : 1;
}
null
は、「nulk」と「nulm」の間でソートされます。ただし、undefined
はalways最後にソートされます。
Elvis演算子も使用できます。
arr = ['Bob', 'charley', 'fudge', 'Fudge', 'biscuit'];
arr.sort(function(s1, s2){
var l=s1.toLowerCase(), m=s2.toLowerCase();
return l===m?0:l>m?1:-1;
});
console.log(arr);
与える:
biscuit,Bob,charley,fudge,Fudge
LocaleCompareメソッドはおそらく大丈夫です...
注:Elvis演算子は、もしそうでなければ、通常は代入を伴う短い形式の「三項演算子」です
?:横を見ると、エルビスのように見えます...
i.eの代わりに:
if (y) {
x = 1;
} else {
x = 2;
}
次を使用できます:
x = y?1:2;
つまり、yがtrueの場合は1(xへの割り当ての場合)を返し、そうでない場合は2(xへの割り当ての場合)を返します。
これは、理解するのに苦労している場合に役立ちます。
var array = ["sort", "Me", "alphabetically", "But", "Ignore", "case"];
console.log('Unordered array ---', array, '------------');
array.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
console.log("Compare '" + a + "' and '" + b + "'");
if( a == b) {
console.log('Comparison result, 0 --- leave as is ');
return 0;
}
if( a > b) {
console.log('Comparison result, 1 --- move '+b+' to before '+a+' ');
return 1;
}
console.log('Comparison result, -1 --- move '+a+' to before '+b+' ');
return -1;
});
console.log('Ordered array ---', array, '------------');
// return logic
/***
If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
***/
文字列配列で.sortIgnoreCase()を呼び出すことができるように、一番上の回答をポリフィルでラップしました
// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
Array.prototype.sortIgnoreCase = function () {
return this.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
};
}
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if( a == b) return 0;
if( a > b) return 1;
return -1;
});
上記の関数では、小文字の2つの値aとbを比較するだけでは、きれいな結果は得られません。
たとえば、配列が[A、a、B、b、c、C、D、d、e、E]であり、上記の関数を使用する場合、正確にその配列があります。何も変わりません。
結果を[A、a、B、b、C、c、D、d、E、e]にするには、2つの小文字の値が等しい場合に再度比較する必要があります。
function caseInsensitiveComparator(valueA, valueB) {
var valueALowerCase = valueA.toLowerCase();
var valueBLowerCase = valueB.toLowerCase();
if (valueALowerCase < valueBLowerCase) {
return -1;
} else if (valueALowerCase > valueBLowerCase) {
return 1;
} else { //valueALowerCase === valueBLowerCase
if (valueA < valueB) {
return -1;
} else if (valueA > valueB) {
return 1;
} else {
return 0;
}
}
}