JavaScriptで配列を名(アルファベット順)で並べ替え


646

JavaScriptを使用して名で並べ替える必要がある配列(配列内の1つのオブジェクトについては以下を参照)を取得しました。どうすればできますか?

var user = {
   bio: null,
   email:  "user@domain.com",
   firstname: "Anna",
   id: 318,
   lastAvatar: null,
   lastMessage: null,
   lastname: "Nickson",
   nickname: "anny"
};

回答:


1067

配列があるとしますusersusers.sort2つの引数を取り、それらを比較する関数(コンパレータ)を使用して渡すことができます。

戻るはず

  • 最初の引数が2番目の引数より小さい場合は負の値(結果の配列で2番目の引数の前に配置する必要があります)
  • 最初の引数の方が大きい場合は正の値(2番目の引数の後に配置する必要があります)
  • これらの2つの要素が等しい場合は0。

今回の場合、2つの要素がaありb、比較a.firstnameしてb.firstname

例:

users.sort(function(a, b){
    if(a.firstname < b.firstname) { return -1; }
    if(a.firstname > b.firstname) { return 1; }
    return 0;
})

このコードはどのタイプでも機能します。

「real life」™では、文字列を比較するときに、大/小文字を無視したり、発音区別符号、ßなどの奇妙な記号を正しくソートしたりすることがよくあるため、を使用することをお勧めしますlocaleCompare。明確にするために他の回答を参照してください。


5
フリギン素晴らしい...私はノードリストをIDでソートしています...魅力のように機能します。トントン!
コーディ、

74
後で来る人にとっては、大文字と小文字が区別されないため、Mrchiefの回答の方が適しています。
mlienau

25
@mlienau、私はそれを良くも悪くも呼ばないでしょう。それはただの別のものです
RiaD 2013

19
@RiaDは十分に公正です。大文字と小文字を含めてアルファベット順に項目を並べ替える多くの場合を考えることはできません。「リンゴ」の前に「ゼブラ」がリストに表示される場合は、非常に便利です。
mlienau 2013

15
このコードは英語圏の国でのみ機能します。他の国では、ovunccetinの回答をでlocaleCompare使用する必要があります。
スポーク2013

545

ES6で可能な最短のコード!

users.sort((a, b) => a.firstname.localeCompare(b.firstname))

String.prototype.localeCompare()基本サポートは普遍的です!


27
あなたが2017年に住んでいるなら、断然最良の答え
nathanbirrell

52
2018年にお住まいの場合もベストアンサーです;)
Simone

49
おそらく、2019にとっても最良の答えになるでしょう。
Ahmad Maleki

23
2020年かな?またはnaaa?
kspearrin

15
ああ、2030年に地球は洪水になり、これは山でのみ機能します。
Starfs

343

このようなもの:

array.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
 if (nameA < nameB) //sort string ascending
  return -1;
 if (nameA > nameB)
  return 1;
 return 0; //default return value (no sorting)
});

43
文字列を並べ替える場合、「toLowerCase()」は非常に重要です。大文字が並べ替えに影響する可能性があります。
MarzSocks 2014年

3
場合、誰が何toLowerCaseメソッドの影響を疑問に思っている、それはあまりありません:'a'>'A' //true 'z'>'a' //true 'A'>'z' //false
SimplGy

14
@SimplGyその影響はあなたがそれを認めているよりも少し大きいと私は主張します。受け入れ答えにコメントで述べたように例えば、それはあなたのソート関数は、文字列でソートするかどうかを知っておくことが重要です'Zebra'文字列よりも高い'apple'あなたが使用していない場合、それはやるだろう、.toLowerCase()
PrinceTyke 2015

1
@PrinceTykeそうだね。'Z' < 'a' // trueおよび'z' < 'a' // false
SimplGy 2015

2
すべての有効なポイントと私は、ソートは常に「依存する」種類のことだと言います。名前で並べ替える場合は、大文字と小文字を区別する必要はありません。他の場合ではそうかもしれません。とにかく、コアとなるアイデアを得たら、特定の状況に適応することは難しくないと思います。
Mrchief、2015

336

比較される文字列にUnicode文字が含まれている場合、次のようなクラスのlocaleCompare関数を使用できStringます。

users.sort(function(a,b){
    return a.firstname.localeCompare(b.firstname);
})

3
String.localeCompareはSafariおよびIE <11をサポートしていません:)
CORSAIR

13
サポートされている@CORSAIR、それはサポートされていない2番目と3番目のパラメーターにすぎません。
Codler 2014年

6
@CORSAIR例の使用法は、すべての主要なIEブラウザーでサポートされています:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。LocaleCompareも大文字と小文字を考慮しているため、この実装はベストプラクティスと見なす必要があると思います。
Matt Jensen

9
users.sort((a、b)=> a.firstname.localeCompare(b.firstname))// Short n sweet ES6バージョン!
Nachiketha 2017

4
戦車仲間。ES6での使用users.sort((a, b) => a.name.localeCompare(b.name))
Mohmmad Ebrahimi Aval

32

素敵な小さなES6ワンライナー:

users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0);

2
これは、等しい値を適切に処理しないため、不完全です。
Karl-JohanSjögren2017

1
もちろん、それを見つけてくれてありがとう、値が一致するかどうかのチェックを追加しました
Sam Logan

悪くないですが、1行にすべてを入れたい場合は、ネストされた3進数が読みにくくなる可能性があります
russter

24

localeCompareを使用できますが、誤った値がないかキーもチェックする必要があります

1つのエントリにlnameがない場合、以下のコードは機能しません。

obj.sort((a, b) => a.lname.localeCompare(b.lname))

だから私たちは以下のような偽の値をチェックする必要があります

let obj=[
{name:'john',lname:'doe',address:'Alaska'},
{name:'tom',lname:'hopes',address:'California'},
{name:'harry',address:'Texas'}
]
let field='lname';
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));

または

lodashを使用できます。これは非常に簡単です。戻り値、つまり数値か文字列かを検出し、それに応じてソートを行います。

import sortBy from 'lodash/sortBy';
sortBy(obj,'name')

https://lodash.com/docs/4.17.5#sortBy


2
ロダッシュはかなりきれいです!聞いたことがない。よく働く!
Derk Jan Speelman

15

underscorejsは、非常に優れた_.sortBy関数を提供します。

_.sortBy([{a:1},{a:3},{a:2}], "a")

または、カスタムのソート関数を使用できます。

_.sortBy([{a:"b"},{a:"c"},{a:"a"}], function(i) {return i.a.toLowerCase()})

2
2番目の例では、文字列を返します。sortBy返される値は文字列であるため、アルファベット順のソートを行い、検出?ありがとう
superjos 2014年

12

名前や、ñáéíóú(スペイン語では一般的)などの特殊文字を使用して並べ替える場合は、params ロケール(この場合はスペイン語のes)と次ようなオプションを使用できます

let user = [{'firstname': 'Az'},{'firstname': 'Áb'},{'firstname':'ay'},{'firstname': 'Ña'},{'firstname': 'Nz'},{'firstname': 'ny'}];


user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'}))


console.log(user)

公式のロケールオプションは、ここiana、es(スペイン語)、de(ドイツ語)、fr(フランス語)にあります。感度 ベース手段:

ベース文字が異なる文字列のみが不等として比較されます。例:a≠b、a =á、a =A。


8

基本的にメソッドsortで配列を並べ替えることができますが、オブジェクトを並べ替える場合は、配列のsortメソッドに関数を渡す必要があるため、配列を使用した例を示します

user = [{
bio: "<null>",
email: "user@domain.com",
firstname: 'Anna',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Senad',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Muhamed',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
}];

var ar = user.sort(function(a, b)
{
  var nA = a.firstname.toLowerCase();
  var nB = b.firstname.toLowerCase();

  if(nA < nB)
    return -1;
  else if(nA > nB)
    return 1;
 return 0;
});

なぜ最後に0を返すのですか?
のび太

=、文字列が同じ場合
SenadMeškin15年

しかし、その場合はelse削除されるべきではありませんか?それ以外の場合はreturn 0読み込まれません
のび太

2
それは「else」ではなく、「else if」です
セナド・メスキン


8

よりコンパクトな表記:

user.sort(function(a, b){
    return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1;
})

よりコンパクトですが、その契約に違反しています:sign(f(a, b)) =-sign(f(b, a))(a = bの場合)
RiaD 2014年

3
return a.firstname == b.firstname===完全性のために使用する必要があります
puiu 2015年

6

asecとdescの両方のソートでも、uはこれを使用できます。昇順のソートまたは降順のソートを指定する変数SortTypeがあるとします。

 users.sort(function(a,b){
            return   sortType==="asc"? a.firstName.localeCompare( b.firstName): -( a.firstName.localeCompare(  b.firstName));
        })

5

一般化された関数は以下のように書くことができます

    function getSortedData(data, prop, isAsc) {
        return data.sort((a, b) => (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1));
   }

以下のパラメータを渡すことができます

  1. ソートしたいデータ
  2. それによるデータのプロパティはソートする必要があります
  3. 最後のパラメーターはブール型です。昇順または降順のどちらでソートするかをチェックします

4

試す

users.sort((a,b)=> (a.firstname>b.firstname)*2-1)


2
sort関数は-1,0,1を返します。これは-1,1のみを返します。
Radu Luncasu

@RaduLuncasu-上記のソリューションが間違った結果をもたらすことを示すテストデータ(ユーザー配列)を提供できますか?(私が知る限り、ゼロが足りなくても問題ありません)
KamilKiełczewski19年

compareFunction(a、b)が0を返す場合、aとbは互いに変更せずに、すべての異なる要素に関してソートされます。
Radu Luncasu


@RaduLuncasuわかりましたが、その情報はゼロが必須であることを意味しません。それを示す最良の方法は、機能しないデータを準備することです-しかし、これは不可能であることがわかっています-たとえば[9,8,7,6,5,1,2,3].sort((a,b) => a<b ? -1 : 1)
KamilKiełczewski'19 / 06/27

3

これをオブジェクトに使用できます

transform(array: any[], field: string): any[] {
return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);}

2

簡単に言えば、この方法を使用できます

users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1});

1

組み込みの配列メソッド-を使用できますsort。このメソッドは、パラメータとしてコールバックメソッドを取ります



    // custom sort function to be passed as param/callback to the Array's sort method
    function myCustomSort(a, b) {
        return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1;
    }

    // Actual method to be called by entity that needs sorting feature
    function sortStrings() {
        var op = Array.prototype.sort.call(arguments, myCustomSort);
    }

    // Testing the implementation
    var sortedArray = sortStrings("Burger", "Mayo1", "Pizza", "boxes", "Apples", "Mayo");
    console.log(sortedArray); //["Apples", "boxes", "Burger", "Mayo", "Mayo1", "Pizza"]


このコードを理解するための注意点。

  1. この場合のカスタムメソッドは myCustomSort(入力配列からの)要素ペアの比較ごとに+1または-1を返す必要があります。
  2. 大文字小文字の違いが並べ替えプロセスの正確さに影響しないように、カスタム並べ替えコールバックメソッドでtoLowerCase()/ toUpperCase()を使用します。

これが十分に明確な説明であることを願っています。必要に応じて、コメントしてください。詳しい情報が必要です。

乾杯!


等しいかどうかのチェックではなく、以下のチェックのみを実行するため、適切な答えではありません。
Steel Brain

また、2011年以降に発表された回答のどれと比較しても、新たなメリットはありません。
amenthes

1

キーでソートするために、上位の回答をプロトタイプにプッシュしました。

Array.prototype.alphaSortByKey= function (key) {
    this.sort(function (a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    });
    return this;
};

0

大文字と小文字を区別するために、類似したものを使用できます

users.sort(function(a, b){

  //compare two values
  if(a.firstname.toLowerCase() < b.firstname.toLowerCase()) return -1;
  if(a.firstname.toLowerCase() > b.firstname.toLowerCase()) return 1;
  return 0;

})

7
Mrchiefの回答と同じです。さらに、toLowerCaseが比較ごとに2回ではなく4回実行されるという欠点もあります。
amenthes

0

私の実装は古いESバージョンでうまく機能します:

sortObject = function(data) {
    var keys = Object.keys(data);
    var result = {};

    keys.sort();

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        result[key] = data[key];
    }

    return result;
};

0

念のため、名前付きソート関数が必要な場合の構文は次のとおりです。

let sortFunction = (a, b) => {
 if(a.firstname < b.firstname) { return -1; }
 if(a.firstname > b.firstname) { return 1; }
 return 0;
})
users.sort(sortFunction)

以下は機能しないことに注意してください。

users.sort(sortFunction(a,b))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.