3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[JavaScript] オブジェクトの値で配列をソートする

Last updated at Posted at 2021-04-15

オブジェクトを格納した配列に対して,オブジェクトの特定のプロパティを基準にソートする方法を紹介します。

この配列を age でソートしたい

const arr = [
  {name: 'David', age: 25},
  {name: 'Bob', age: 30},
  {name: 'John', age: 25},
  {name: 'Tom', age: 37},
  {name: 'Rachel', age: 28},
  {name: 'Sam', age: 40},
  {name: 'Alice', age: 25},
];

結論

const arr = [
  {name: 'David', age: 25},
  {name: 'Bob', age: 30},
  {name: 'John', age: 25},
  {name: 'Tom', age: 37},
  {name: 'Rachel', age: 28},
  {name: 'Sam', age: 40},
  {name: 'Alice', age: 25},
];

const newArr = [...arr].sort((a, b) => (a.age > b.age) ? 1 : -1);
console.log(newArr);
[
  { name: 'Alice', age: 25 },
  { name: 'John', age: 25 },
  { name: 'David', age: 25 },
  { name: 'Rachel', age: 28 },
  { name: 'Bob', age: 30 },
  { name: 'Tom', age: 37 },
  { name: 'Sam', age: 40 }
]

age が同じ場合は name でソート

const arr = [
  {name: 'David', age: 25},
  {name: 'Bob', age: 30},
  {name: 'John', age: 25},
  {name: 'Tom', age: 37},
  {name: 'Rachel', age: 28},
  {name: 'Sam', age: 40},
  {name: 'Alice', age: 25},
];

const newArr = [...arr].sort((a, b) => (a.age > b.age) ? 1 : (a.age === b.age) ? ((a.name > b.name) ? 1 : -1) : -1);
console.log(newArr);
[
  { name: 'Alice', age: 25 },
  { name: 'David', age: 25 },
  { name: 'John', age: 25 },
  { name: 'Rachel', age: 28 },
  { name: 'Bob', age: 30 },
  { name: 'Tom', age: 37 },
  { name: 'Sam', age: 40 }
]

文字列の大小比較は辞書順ですが「大文字は小文字より小さい」などの直感的にわからない規則もあるので注意が必要です。

解説

MDN Web Docs の Array.prototype.sort() を読むのが早いです。

比較関数 compare(a, b) の使い方を簡単に言うと
a, b の順 → -1
b, a の順 → 1

コールバック関数の処理部分が少しややこしいです。

(a.age > b.age) ? 1 : (a.age === b.age) ? ((a.name > b.name) ? 1 : -1) : -1

if文で書くとこうなります(分かりやすいように冗長な記述にしています)。

if(a.age > b.age){
    return 1;
}else{
    if(a.age === b.age){
        if(a.name > b.name){
            return 1;
        }else{
           return -1;
        }
    }else{
        return -1;
    }
}

蛇足(配列のコピーについて)

sort() は配列そのものを変更する破壊的なメソッドです。
元の配列を維持するために [...arr] とコピーしてから使いました。
配列のコピーは arr.slice()arr.concat() でもできます。

但し,いずれのコピーも内部のオブジェクトは shallow copy であることに注意してください。

const arr = [
  {name: 'David', age: 25},
  {name: 'Bob', age: 30},
  {name: 'John', age: 25},
  {name: 'Tom', age: 37},
  {name: 'Rachel', age: 28},
  {name: 'Sam', age: 40},
  {name: 'Alice', age: 25},
];

const newArr = [...arr]; // 配列のコピーを作成
newArr[0].name = 'Hello';  // 'David' を 'Hello' に変更

console.log(arr);
[
  { name: 'Hello', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'John', age: 25 },
  { name: 'Tom', age: 37 },
  { name: 'Rachel', age: 28 },
  { name: 'Sam', age: 40 },
  { name: 'Alice', age: 25 }
]

オブジェクトを deep copy したい時は,lodash の cloneDeep() を使うのがおすすめです。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?