L08084のブログ

技術記事の執筆は、祈りに近い

【JavaScript】reduceを使ってオブジェクトの配列から一番大きいIDを取得する

モチベーション

強力そうだけどいまいち使いこなせていない関数筆頭のArray.prototype.reduce()について、ちゃんと習得したいという思い

バージョン情報

  • Angular: 6.0.3
  • Typescript: 2.7.2

今回やること

下記のオブジェクトの配列から、reduce()を使って値が最大のIDを取得してみる

  weapons = [
    {id: 1, name: 'ブロードソード', power: 117},
    {id: 2, name: '太陽の直剣', power: 112},
    {id: 3, name: '輪の騎士の直剣', power: 120}
  ];

コードとしては、下記のように書けば最大のIDを取得することができる

// リスト内で一番大きいIDを取得
const max = this.weapons.reduce((a, b) => a > b.id ? a : b.id, 0);

(a, b) => a > b.id ? a : b.idは、reduceのコールバック関数、0はreduceの最初の引数になるinitialValueとなる。
コールバック関数の引数aはコールバックの戻り値を累積するaccumulator(ひとつ前の処理結果または initialValue を指す)にあたり、bは現在処理されている配列要素であるcurrentValueとなる。
処理内容としては、「0と最初の配列要素のidと比較して、大きい方を次の配列要素のidと比較して、大きかった方をさらにその次の配列要素のidと比較して...」という流れになる。

上記のサンプルコードを使用して、配列にオブジェクトを追加するコードを書いてみる

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
            名前<input type="text" (keyup)="name=$event.target.value">
          <button (click)="addWeapon()">武器を追加</button>
          <ul>
            <li *ngFor="let weapon of weapons">
              ID:{{ weapon.id }} {{ weapon.name }} 攻撃力:{{ weapon.power}}
            </li>
          </ul>
`
})
export class AppComponent {
  name: string;
  weapons = [
    {id: 1, name: 'ブロードソード', power: 117},
    {id: 2, name: '太陽の直剣', power: 112},
    {id: 3, name: '輪の騎士の直剣', power: 120}
  ];

  // 新しい武器を追加する
  public addWeapon(): void {
    // リスト内で一番大きいIDを取得
    const max = this.weapons.reduce((a, b) => a > b.id ? a : b.id, 0);
    // 新しい武器をリストに追加
    this.weapons.push({
      id: max + 1,
      name: this.name,
      power: 200
    });
  }
}

動作確認

サンプルコードを実際に動かしてみる

テキストフォームに、武器名を入力して... f:id:l08084:20180819160226p:plain

「武器を追加」ボタンを押すと、最大のIDが採番された状態でリストに武器が追加されていることがわかる f:id:l08084:20180819160244p:plain

参考サイト

Array.prototype.reduce() - JavaScript | MDN