blog

map() filter() reduce() の使用法

.map()がどのように機能するのか、簡単な例で説明しましょう。複数のオブジェクトを含む一連の配列が提示されたとします。これを実現するには複数の方法があると思います。...

Mar 30, 2020 · 4 min. read
シェア

map()

簡単な例を挙げて、その仕組みを説明しましょう。 オブジェクトの配列を受け取り、その配列の各オブジェクトが人だとします。

var c = [
    {
        'id': 0x14,
        'name': 'Captain\x20Piett'
    },
    {
        'id': 0x18,
        'name': 'General\x20Veers'
    },
    {
        'id': 0x38,
        'name': 'Admiral\x20Ozzel'
    },
    {
        'id': 0x58,
        'name': 'Commander\x20Jerjerrod'
    }
];
[
    0x14,
    0x18,
    0x38,
    0x58
];

.forEach()、.for(.....of)、または単純な.for()

比較してみましょう!

で .forEach()

var c = [];
officers.forEach(function (a) {
    c.push(a.id);
});

最初に空の配列を作らなければならないことにお気づきでしょうか?.map()がどのようにそれを行うか見てみましょう。

var obj = officers.map(function (c) {
    return c.id;
});

アロー関数を使えば、よりコンパクトになります。

const officersIds = officers.map(officer => officer.id);

では、.map()はどのように動作するのでしょうか?実際には、配列の各要素を一度だけ繰り返し処理し、新しい値を返します。ひとつ覚えておきたいのは、この返されるデータの長さは元の配列の長さと同じだということです。

filter()

配列があり、その中の一部の要素だけが欲しい場合はどうすればよいでしょうか?そこで便利なのが .filter() です。

var foo = [
    {
        'id': 0x2,
        'name': 'Wedge\x20Antilles',
        'a': 'Rebels'
    },
    {
        'id': 0x8,
        'name': 'Ciena\x20Ree',
        'a': 'Empire'
    },
    {
        'id': 0x28,
        'name': 'Iden\x20Versio',
        'a': 'Empire'
    },
    {
        'id': 0x42,
        'name': 'Thane\x20Kyrell',
        'a': 'Rebels'
    }
];

もし、反乱軍パイロットと帝国軍パイロットの2つの配列が必要なら、.filter()~を使えば簡単です。

var a = pilots.filter(function (bar) {
    return bar.b === 'Rebels';
});
var foo = pilots.filter(function (c) {
    return c.b === 'Empire';
});

また、アロー関数を使えば、よりエレガントに表現することもできます:

const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

要約すると、コールバック関数が true を返せば、その要素は返された配列に表示され、false を返せば表示されません。

reduce()

簡単な例で、.reduce() の使い方を説明します。パイロットの人数と飛行経験を含む配列があるとします。

var b = [
    {
        'id': 0xa,
        'name': 'Poe\x20Dameron',
        'bar': 0xe
    },
    {
        'id': 0x2,
        'name': 'Temmin\x20\x27Snap\x27\x20Wexley',
        'bar': 0x1e
    },
    {
        'id': 0x29,
        'name': 'Tallissan\x20Lintra',
        'bar': 0x10
    },
    {
        'id': 0x63,
        'name': 'Ello\x20Asty',
        'bar': 0x16
    }
];

全パイロットの総飛行年数を知りたい場合。.reduce()を使用すると非常に直感的です。

var c = pilots.reduce(function (b, foo) {
    return b + foo.bar;
}, 0x0);

アキュムレータは最初に 0 で初期化され、必要に応じて他の値で初期化できることがわかります。 各要素に対してコールバック関数を実行した後、 reduce は最終的な値を返します。

arrow関数を使用してコードを効率化することもできます:

const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);

どのパイロットが最も長く飛行しているかを知る必要がある場合は、この方法で知ることができます:

var mostExpPilot = pilots.reduce(function (oldest, pilot) {
 return (oldest.years 
 0) > pilot.years ? oldest : pilot;
}, {});

要約すると、reduceは直感的に配列内の指定した値やオブジェクトを返します。

map() .filter() .reduce() コンバイン

.map()と.filter()はどちらも配列を返すので、連鎖的なプログラミングで一緒に使うのは簡単です。

次のようなデータがあるとしましょう:

var obj = [
    {
        'id': 0x5,
        'name': 'Luke\x20Skywalker',
        'bar': 0x62,
        'c': 0x38,
        'a': !false
    },
    {
        'id': 0x52,
        'name': 'Sabine\x20Wren',
        'bar': 0x49,
        'c': 0x63,
        'a': false
    },
    {
        'id': 0x16,
        'name': 'Zeb\x20Orellios',
        'bar': 0x14,
        'c': 0x3b,
        'a': false
    },
    {
        'id': 0xf,
        'name': 'Ezra\x20Bridger',
        'bar': 0x2b,
        'c': 0x43,
        'a': !false
    },
    {
        'id': 0xb,
        'name': 'Caleb\x20Dume',
        'bar': 0x47,
        'c': 0x55,
        'a': !false
    }
];

目標は、属性forceを持つユーザーの合計値を取得することです。 読者は、まずこれを自分で考え、先に学んだことを統合するために使用することができ、それは次のように処理することができます。

var b = personnel.filter(function (foo) { return foo.a; }).map(function (c) { return c.obj + c.bar; }).reduce(function (A, C) { return A + C; }, 0x0);

同様に、矢印式で効率化することもできます。

const totalJediScore = personnel
 .filter(person => person.isForceUser)
 .map(jedi => jedi.pilotingScore + jedi.shootingScore)
 .reduce((acc, score) => acc + score, 0);
Read next

データ構造の知識ポイントのリスト

a. i > 1のとき、ノードiの両子ノードは⌊i/2⌋と番号付けされます。すなわち、iが偶数のとき、その両子ノードはi/2と番号付けされ、そのノードは左子ノードです。b. 2i <= nのとき、ノードiの左子ノードは2iと番号付けされ、そうでなければ左子ノードはありません。+1 <= n...

Mar 30, 2020 · 25 min read