web-dev-qa-db-ja.com

JavaScriptで大文字と小文字を区別しないソートを実行する方法は?

JavaScriptで並べ替える必要がある文字列の配列がありますが、大文字と小文字を区別しません。これを実行するには?

183

(ほぼ:)ワンライナー

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});

結果として

[ 'bar', 'Foo' ]

ながら

["Foo", "bar"].sort();

結果として

[ 'Foo', 'bar' ]
341
Ivan Krechetov
myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

編集:パフォーマンスを念頭に置いているのではなく、このテクニックを説明するために最初に書いたことに注意してください。よりコンパクトなソリューションについては、@ Ivan Krechetovの回答も参照してください。

58
ron tornambe
arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if (a == b) return 0;
    if (a > b) return 1;
    return -1;
});
24

この古い質問を再検討する時が来ました。

toLowerCaseに依存するソリューションを使用しないでください。それらは非効率的であり、一部の言語(トルコ語では単に動作しない例えば)。これを好む:

['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))

ブラウザの互換性について documentation を確認してください。また、sensitivityオプションについて知っていることはすべてあります。

24
ZunTzu

入力配列の要素の順序に関係なく同じ順序を保証したい場合は、 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;
});
10
Aalex Gabi

新しい Intl.Collator().compare を使用することもできます。MDNごとに、配列をソートするときに より効率的 です。欠点は、古いブラウザではサポートされていないことです。 MDNは、Safariではまったくサポートされていないと述べています。 Intl.Collator がサポートされていると記載されているため、検証する必要があります。

大きな配列の並べ替えなど、多数の文字列を比較する場合は、Intl.Collat​​orオブジェクトを作成し、compareプロパティで提供される関数を使用することをお勧めします

["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
8
mateuscb

.sort()のケースを.toLowerCase()で正規化します。

4
user1106925

他の答えは、配列に文字列が含まれていることを前提としています。配列に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」の間でソートされます。ただし、undefinedalways最後にソートされます。

3
John Henckel

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への割り当ての場合)を返します。

2
AndyS

これは、理解するのに苦労している場合に役立ちます。

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.
***/

http://jsfiddle.net/ianjamieson/wmxn2ram/1/

0
Ian Jamieson

文字列配列で.sortIgnoreCase()を呼び出すことができるように、一番上の回答をポリフィルでラップしました

// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
    Array.prototype.sortIgnoreCase = function () {
        return this.sort(function (a, b) {
            return a.toLowerCase().localeCompare(b.toLowerCase());
        });
    };
}
0
Jason
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;
        }
    }
}
0
Envy