LoginSignup
0
1

配列内のオブジェクト、任意の値を比較してランキングを作成(練習)

Last updated at Posted at 2024-04-25

「配列内のオブジェクト」ということなので、以下のようなコードで実験用の配列を作成していきます。

/*---配列内にオブジェクトを収めるサンプルコード ---*/

const arr = [...Array(10)].map((_, i) => {
  return {
	  index: i + 1,
	  number: (Math.random() * 100),
	}
})

console.log(arr);
  // 結果
[{
  index: 1,
  number: 91.25240273034892
}, {
  index: 2,
  number: 50.30337793565278
}, {
  index: 3,
  number: 56.7219849866174
}, {
  index: 4,
  number: 78.14357103773145
}, {
  index: 5,
  number: 56.00559517743395
}, {
  index: 6,
  number: 83.7587424204647
}, {
  index: 7,
  number: 97.54322322663951
}, {
  index: 8,
  number: 96.49660404863312
}, {
  index: 9,
  number: 24.422683577051842
}, {
  index: 10,
  number: 78.23240765349418
}]
  • 要素数10の配列、要素にオブジェクト
  • 「number」の値はrandom()なので実行毎に数値が変わる
  • map()のreturnをオブジェクトに出来ることが地味にビックリ

やりたい事

  • 各「number」の値を比較して、ランキングを作成したい
  • sort()系を使い、値の比較と並び替え
  • 配列要素を順番に取り出し、ベストやワーストを出す

そして、作成したのが以下のコードになります。

/*---ランキングを作るコード ---*/

const ranking = (arr, key, n) => {  
	const arr2 = arr.toSorted((a, b) => (b[key] - a[key]) * Math.sign(n));
    const order = [...Array(Math.abs(n)).keys()]
	    .map(e => arr2.at(e));
				
	order.unshift({
	      index: 0, 
		  title:`${n > 0 ? 'ベスト': 'ワースト'}${Math.abs(n)}`,
    });
    return order;
}

const bestRank = ranking(arr, 'number', 3);
const worstRank = ranking(arr, 'number', -3);
console.log(bestRank);

  // 結果
[{
  index: 0,
  title: "ベスト3"
}, {
  index: 7,
  number: 97.54322322663951
}, {
  index: 8,
  number: 96.49660404863312
}, {
  index: 1,
  number: 91.25240273034892
}]
console.log(worstRank);

 // 結果
[{
  index: 0,
  title: "ワースト3"
}, {
  index: 9,
  number: 24.422683577051842
}, {
  index: 2,
  number: 50.30337793565278
}, {
  index: 5,
  number: 56.00559517743395
}]

.toSorted()

通常、sort()で昇順、降順をさせようと思った時、

  • sort((a, b) => a - b) 昇順
  • sort((a, b) => b - a) 降順

と紹介されている事が多いのですが、コード的に aとb をひっくり返すのが何故か 面倒くさい と思ってしまいました。
とりあえず、b-a に1か-1を掛け算したら、上手く昇順と降順が表現できたので、一先ずこれでOKとしました。
尚、toSorted()は、sort()の非破壊的版 らしいです。積極的に使っていきたいです。

.at()

配列のインデックス番号を指定して読み込みに行くメソッドです。
今までのarr2[i]を使っても良かったのですが、arr2.at(i)がカッコ良さそうな感じがして、なんとなく使って見ました(笑)

今回の昇順降順に関しては、arr2.at(i) で i の値を

  • 0,1,2
  • -1,-2,-3

とすることでランキングのベストとワーストを出せたハズで、そういったコードも作る事は出来たと思うのですが、今回は .toSorted() に任せる事としました。

.find()、最大値

次に、ランキングではないのですが、最大値を持つオブジェクトも出してみようと思います。

/*--- 最大値 を検索、.find()で抽出するコード ---*/

const maxNum = arr.reduce((a, c) => Math.max(a, c.number), 0);
const maxObj = arr.find(e => e.number == maxNum);

console.log(maxObj);
 // 結果
{
  index: 7,
  number: 97.54322322663951
}

.filter()、~未満

ついでに、~未満 も抽出してみます。

/*--- ~未満 を.filter()で抽出するコード ---*/
const belowObj = arr.filter(e => e.number < 55);
console.log(belowObj);
  // 結果
[{
  index: 2,
  number: 50.30337793565278
}, {
  index: 9,
  number: 24.422683577051842
}]

比較条件を別に算出している場合は、.find() や .filter() を使い元のarrから該当要素を抽出する事も出来ますね。

まとめ

  • オブジェクトの値を比較して、配列内のオブジェクトを直接ソート が可能
  • オブジェクトの値で .find() や .filter() をすると、オブジェクト自体の抽出 が可能

という事で、

  • もっと良い方法があるよ
  • もっと簡潔に書けるよ
  • それ、まちがってるよ

などありましたら、コメントでお待ちしています。

参考記事

0
1
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
0
1