Skip to content
This page has been auto-translated and may contain errors.View in English

配列メソッド

docs.scrimba.com

価格のリストがあり、各価格に税金を加えた2番目のリストが欲しいとしましょう。配列をループして合計を計算し、各結果を新しい配列にプッシュするforループを書くことはできます。それは動作しますが、小さなアイデアのための大量の配線です:すべてのアイテムを取り出して変更する。配列メソッドはこの種の作業のために組み込まれたツールです。ループを実行するループをつづることなく、リストに何をしたいかを言うことができ、この章では毎日使うメソッドをカバーしています。これらは配列関数に直接構築されているため、両方を手元に置いておいてください。

map:すべてのアイテムを変更する

mapは**メソッド**です:配列に属し、それに対して作業を行う関数です。mapは各アイテムを与えた小さな関数を通して実行し、結果を収集することで新しい配列を構築します。その関数を渡すと、各アイテムを一度に1つずつ渡されます。

いくつかの価格があり、各価格を2倍にしたいとしましょう:

js
const prices = [2, 4, 6];
const doubled = prices.map((price) => price * 2);
console.log(doubled); // [4, 8, 12]

(price) => price * 2の部分はアロー関数です:1つのアイテム(price)を取ってそれが何になるべきかを返す短い関数です(price * 2)。mapはそれを各アイテムに対して一度呼び出し、各答えを新しい配列の同じ順序で置きます。

mapは配列**メソッド**で、リストを同じ長さの新しいリストに変換します。コールバックを与えます。これはmapがアイテムごとに1回実行する関数で、そのコールバックが返すものが結果の同じ位置のアイテムになります。

js
const prices = [2, 4, 6];
const doubled = prices.map((price) => price * 2);
console.log(doubled); // [4, 8, 12]

これを手動バージョンと比較してください。これは同じことをより多くの動く部分で行います:

js
const prices = [2, 4, 6];
const doubled = [];
for (let i = 0; i < prices.length; i += 1) {
  doubled.push(prices[i] * 2);
}
console.log(doubled); // [4, 8, 12]

ループでは、インデックス、新しい配列、およびpushを管理する必要があります。mapは「各価格を価格掛ける2に変える」と意図を述べ、あなたのために簿記を処理します。

mapは配列を同じ長さの新しい配列に変換します。これは各要素に**コールバック**(渡すそれが呼び出すための関数)を適用することで行われます。インデックスiでのコールバックの戻り値は、結果のインデックスiの要素になります。何もスキップされず、何も追加されないため、形状は保持され、値のみが変わります。

js
const prices = [2, 4, 6];
const withTax = prices.map((price) => price * 1.2);
console.log(withTax); // [2.4, 4.8, 7.2]

コールバックはインデックスと全配列も2番目と3番目の引数として受け取るため、位置が重要な場合はarray.map((value, index) => ...)が利用可能です。それが保持する値は意図です:mapは一目で「同じ長さ、各アイテム変換」と言います。ループではインデックス、カウンター、およびpushから読者がそれを再構築する必要があります。

Junomapmapはリストを取り、同じ長さの新しいリストを与えます。すべてのアイテムが小さな関数を通して実行されます。アロー関数は各アイテムが何に変わるかを言い、mapはそれをすべての順序で行います。ループのみを書いてから2番目のリストを構築する場合は、常にそれを使用してください。
Junomapmapは「すべてのアイテムを同じ長さの新しい配列に変換」します。コールバックはアイテムごとに一度実行され、その戻り値は同じ位置に置かれます。ループプラスプッシュパターンの置き換えとしてそれを見ると、ループの半分は単一の読みやすい行に変わります。
Junomapmapは長さと位置を保持します:インデックスiでのコールバックの戻りが結果のインデックスiになります。位置が重要な場合、コールバックはインデックスと配列も取得します。それはループがカウンターとpushから意図を再構築する場所を読む意図として読みます。

filter:通過したアイテムを保持する

mapがすべてのアイテムを変更するのに対し、filterは一部のみを保持します。各アイテムに対して「はい」または「いいえ」で答える関数を与え、filterは「はい」を得たアイテムのみから新しい配列を構築します。

js
const scores = [40, 75, 90, 55, 88];
const passing = scores.filter((score) => score >= 60);
console.log(passing); // [75, 90, 88]

関数(score) => score >= 60は各スコアに対してtrueまたはfalseを返します。filtertrueであるもの保持し、残りを削除します。新しい配列は元の配列より短くすることができ、順序は決して変わりません。

filterはコールバックがtrueを返すアイテムのみを保持する新しい配列を返します。コールバックは**述語**です:各アイテムについてはい/いいえの質問に答えることが仕事の関数。

js
const scores = [40, 75, 90, 55, 88];
const passing = scores.filter((score) => score >= 60);
console.log(passing); // [75, 90, 88]

結果は入力より短いことが多く、元の順序を保持します。その中にifがあるループと比較して、filterはテストを前面中央に置き、その周りの儀式を削除します。コールバックがすべてに対してtrueを返す場合、完全なコピーが戻されます。すべてに対してfalseを返す場合、空の配列が返されます。

filterは**述語**(はい/いいえの答えを返すことが仕事のコールバック)が保持する要素の新しい配列を返します。長さは保持されていません:結果は空から完全なコピーまで実行され、順序は保持されます。

js
const scores = [40, 75, 90, 55, 88];
const passing = scores.filter((score) => score >= 60);
console.log(passing); // [75, 90, 88]

2つのことは明確に保つ価値があります。まず、filterはアイテムが生き残るかどうかを決定します。アイテムを変更することはありません。選択と変換の両方が必要な場合は、mapと組み合わせてください。次に、コールバックの戻りはブール値に強制されるため、誤って0またはundefinedを返す述語は、保持したいアイテムを削除します。明示的な比較を返し、そのバグクラスは消えます。

Junofilterfilterはテストに合格したアイテムを保持し、残りを削除するため、新しい配列はしばしば短くなります。あなたの関数は各アイテムについて「はい」または「いいえ」で答え、はいのみが通ります。順序は決して変わりません。生き残ったものは開始した順序のままです。
Junofilterfilterはコールバックがtrueを返すアイテムを保持し、同じ長さ以下の新しい配列を提供します。コールバックは述語です:トランスフォーマーではなく、はい/いいえのテスト。すべてtrueは完全なコピーを提供し、すべてfalseは空の配列を提供し、順序は常に保持されます。
Junofilterfilterは選択し、mapは変換し、その分割をきれいに保つことは、それらが非常によく連鎖する理由です。コールバックの戻りはブール値に強制されるため、0またはundefinedをかすめて返す述語は、あなたが望んだアイテムを静かに削除します。明示的な比較を返し、そのバグクラス全体が消えます。

reduce:1つの値に絞る

mapfilterは両方ともアレイを返します。reduceは配列を1つの値に折りたたむもので:合計、最大値、連結された文字列です。他より多くの人々を混乱させるため、ゆっくり進む価値があります。

reduceは配列を歩きながら、その結果を一緒に持ち歩きます。各アイテムで、「これまでの結果と、このアイテムを考えると、新しい結果は何か?」と尋ねます。

js
const prices = [10, 20, 30];
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 60

関数は2つのもの:sum(これまでの実行合計)とprice(現在のアイテム)を取得します。これはsum + priceを返し、次のアイテムの新しい実行合計になります。最後の0は合計が始まる場所です。そのため、0 + 10、その後10 + 20、その後30 + 30と行き、60に着地します。

reduceは**アキュムレータ**(各ステップが更新して渡す実行中の結果)を持つことで、配列全体を1つの値に変えます。コールバックはアキュムレータと現在のアイテムを受け取り、次のステップのアキュムレータを返します。

js
const prices = [10, 20, 30];
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 60

明確にするために2つの引数:sumはアキュムレータ(これまでのアップの値)、priceは現在のアイテム。reduceへの2番目の引数、0は、アキュムレータの開始値です。ステップバイステップ:0で開始、10を加算して10を取得、20を加算して30を取得、30を加算して60を取得。ここのsumという名前はラベルのみです。アキュムレータは、文字列を追加し続けたり、実行最大値を追加したりするなど、任意の型である可能性があります。

reduceは**アキュムレータ**(実行中の結果)を配列を通してスレッドすることで、配列を1つの値に折ります。コールバックは(accumulator, currentItem) => nextAccumulatorで、その戻りが次のステップに渡されるアキュムレータになります。reduceへの2番目の引数は初期アキュムレータです。

js
const prices = [10, 20, 30];
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 60

2つの実用的なルールがほとんどのreduceバグを保存します。常に初期値を渡してください:それなしで、reduceは最初の要素をシードとして使用し、2番目で開始します。空の配列でスローされ、アキュムレータ型が要素型と異なる場合、動作が静かに変更されます。コールバックを通ったすべてのパスはアキュムレータを返す必要があります。複数行本体でreturnを忘れると、次のステップのアキュムレータがundefinedのままになります。reduceはこれらのメソッドの最も一般的で、mapfilterは両方ともreduceとして書くことができます。これは、それが読めなくなるのも簡単な理由です。1つの値に折りたたむときにそれを使用し、そうでないときはより単純な何かに達してください。

Junoreducereduceはリスト全体を通じて実行中の結果を携帯し、各アイテムで更新します。コールバックは、これまでの結果と現在のアイテムを取得し、新しい結果を返します。最後の引数は開始位置で、通常は合計のための0で、これはステップバイステップで大声で読んだ瞬間私にクリックしました。
Junoreducereduceはアキュムレータを使用して配列を1つの値に絞ります:各ステップが更新して渡す実行中の結果。コールバックは(accumulator, item)で、最後の引数はアキュムレータをシードします。数字である必要はありません。アキュムレータは、構築する文字列または実行最大値である可能性があります。
Junoreduce 常に初期値を渡してください。そうしないと、reduceは最初の要素からシードし、空の配列でスローされます。コールバックを通ったすべてのパスはアキュムレータを返す必要があります。そうしないと、次のステップがundefinedを取得します。これらのメソッドの最も一般的で読めなくなるのは簡単です。1つの値に折りたたむために使用し、そうでないときはより単純な何かに達してください。

find、some、およびevery

これら3つはfilterの親戚です:テストを配列全体に対して実行しますが、新しい配列の代わりに、より狭い質問に答えます。

findはテストに合格したすべてのリストではなく、最初のアイテムをあなたに与えます。someeveryは配列全体についてのはい/いいえの質問に答えます。

js
const scores = [40, 75, 90, 55];

const firstPass = scores.find((score) => score >= 60);
console.log(firstPass); // 75

const anyPass = scores.some((score) => score >= 60);
console.log(anyPass); // true

const allPass = scores.every((score) => score >= 60);
console.log(allPass); // false

findは最初の一致したアイテム(75)を返します。someは「何かアイテムが合格しましたか?」と尋ね、少なくとも1つが行われたためtrueを返します。everyは「すべてが合格しましたか?」と尋ね、4055が行わなかったためfalseを返します。

filterと同じ述語スタイル、3つの異なる答え。findは**最初の一致したアイテム**を返します(一致しない場合はundefined)。someは、少なくとも1つのアイテムが合格する場合はtrueを返します。everyは、すべてが合格する場合のみtrueを返します。

js
const scores = [40, 75, 90, 55];

console.log(scores.find((score) => score >= 60)); // 75
console.log(scores.some((score) => score >= 60)); // true
console.log(scores.every((score) => score >= 60)); // false

フィルターされたリストではなく、1つのアイテムが必要な場合はfindに手を伸ばし、コレクションについてのはい/いいえの質問のみが必要な場合はsomeまたはeveryに手を伸ばしてください。filter(...).length > 0someが行うところで使用して動作しますが、すべてのアイテムをチェックして、someが直接答える質問に答えるために使い捨て配列を構築します。

3つの述語駆動型クエリは、新しい配列を構築するのではなく、早期に停止します。findは**最初の一致要素**またはundefinedを返します。someは最初の合格要素でtrueを返します。everyは最初の失敗したものでfalseを返します。

js
const scores = [40, 75, 90, 55];

console.log(scores.find((score) => score >= 60)); // 75
console.log(scores.some((score) => score >= 60)); // true
console.log(scores.every((score) => score >= 60)); // false

短時間結果は要点です:someeveryは答えが決まった瞬間に停止するため、配列全体をフィルタリングするより安く、ブール値のみが必要な場合。エッジケース:findundefinedを返すのは、実際のundefinedを見つけるのと区別できないため、戻り値ではなく、気にするコールバックテストします。そして空の配列ではsomeは常にfalseeveryは常にtrueです(空虚に、失敗するアイテムがないため)。これは正しいですが、初めて人々を驚かせます。

Junofind, some, and everyfindは、リスト全体ではなく、テストに合格した最初のアイテムをあなたに与えます。someは「誰か合格しましたか?」と尋ね、everyは「すべてが合格しましたか?」と尋ねます。両方ともtrueまたはfalseで答えます。1つのアイテムまたははい/いいえの答えが必要な場合、フィルタリングされた配列ではなく、これらを使用してください。
Junofind, some, and everyfilterと同じ述語、3つの狭い答え:findは最初の一致またはundefinedを与え、someは何か合格した場合は真で、everyはすべてが合格した場合のみ真です。1つのアイテムまたはブール値が必要な場合は、filter(...).lengthの代わりにこれらに手を伸ばしてください。意図を言い、使い捨て配列の構築をスキップします。
Junofind, some, and everysomeeveryは短期間結果し、答えが決まった瞬間に停止し、ブール値のために配列全体をフィルタリングします。2つのエッジを見てください:findundefinedを返すのは、実際のundefinedを見つけるのと同じように見え、空の配列ではsomeは常に偽でeveryは常に真です。両方は正しく、両方は人々を1回驚かせます。

チェーン化と読みやすさの維持

上記のメソッドは、それらを組み合わせると報酬を得るデザインを共有しています:各メソッドは新しい値を返し、元の配列をそのままにします。

mapfilterなどは、開始した配列を変更することはありません。新しい配列(または値)を提供し、元のままにします。

js
const prices = [10, 20, 30];
const doubled = prices.map((price) => price * 2);
console.log(doubled); // [20, 40, 60]
console.log(prices); // [10, 20, 30]

mapfilterは両方ともアレイを返すため、それらを並べることができます:最初にフィルター、次に生存者をマップします。

js
const prices = [10, 20, 30, 40];
const bigDoubled = prices.filter((price) => price >= 20).map((price) => price * 2);
console.log(bigDoubled); // [40, 60, 80]

これらのメソッドは元のを変更せずに新しい配列と値を返します。**不変性**と呼ばれるプロパティ:ソースデータはそのまま残ります。これがチェーン化を安全にする理由です。filterが配列を返すため、結果に対して直接mapを呼び出すことができます:

js
const prices = [10, 20, 30, 40];
const bigDoubled = prices.filter((price) => price >= 20).map((price) => price * 2);
console.log(bigDoubled); // [40, 60, 80]

チェーンを上から下へパイプラインとして読んでください:20以上の価格を保持し、次に各生存者を2倍にします。順序が重要です。最初にフィルターすることは、mapがより少ないアイテムで実行されることを意味するためです。チェーン化は2つまたは3つのステップまで読むことがよくあります。それを超えて、名前付きの中間変数または単純なループは、1つの長いチェーンより明確なことが多いです。

これらのメソッドは非ミューティング:新しい配列と値を返し、ソースをそのままにします。その**不変性**は、ステップが共有配列に戻って編集されないため、filter(...).map(...)チェーンをパイプラインとして安全に読める理由です。

js
const prices = [10, 20, 30, 40];
const bigDoubled = prices.filter((price) => price >= 20).map((price) => price * 2);
console.log(bigDoubled); // [40, 60, 80]

チェーン化がヘルプまたはハートするかどうかを決定する2つの判断呼び出し。まず、コスト:各ステップは配列を歩いて新しい配列を割り当てるため、3ステップチェーンは3つのパスと2つの中間配列を作成します。毎日出会うサイズでは、それは無関係で、読みやすさが勝ちます。ホットパスの大きな配列の場合、重要である可能性があり、1つのパスまたは仕事を行うreduceが答えです。次に、明確さ:チェーンは各ステップが1つの明確なアイデアの場合、その場所を獲得します。コールバックが枝の本体を成長させたり、チェーンが3つのステップを超えたりする瞬間、単純なforループは通常、よく名前が付けられた変数で読みやすいです。最も短いチェームではなく、チームメイトが最も速く理解するバージョンを優先します。

JunoChaining and staying readable これらのメソッドは、開始する配列を変更することはなく、新しいものを与えるため、元のは常に安全です。filtermapは両方ともアレイを返すため、チェーン化することができます:最初にフィルター、次に左側をマップします。上から下へチェーンを読み、一度に1ステップ。
JunoChaining and staying readable 不変性、元の配列をそのままにすることは、チェーンを安全にする理由です。filter(...).map(...)をパイプラインとして上から下へ読み、順序が重要であることに注意してください。最初にフィルタリングすることは、より少ないアイテムをマップすることを意味するためです。2つまたは3つのステップを超えて、名前付き変数または単純なループは通常、1つの長いチェーンより明確に読みます。
JunoChaining and staying readable 各ステップはパスと割り当てであるため、チェーンは毎日のサイズでは問題がなく、ホットパス上で大きなデータ上の1つのループまたはreduceに折りたたむ価値があります。明確さは他の呼び出しです:チェーンは各ステップが1つの明確なアイデアの場合、その場所を獲得し、コールバックが枝を成長させた後、単純なループが勝ちます。最も短いのではなく、チームメイトが最も速く読むバージョンを書いてください。

次に進むべきところ

mapfilter、およびreduceは、リストで行う最大のものをカバーします:それを変換するか、狭くするか、または折りたたんでください。findsome、およびeveryは、より狭い質問に答えます。これらが自然に感じられたら、配列上のforループのほとんどは、あなたが意味したことを言う1つまたは2行に変わります。

次の自然なステップはオブジェクトで、配列はプレーンな数字と文字列よりも豊かなアイテムを保持し始め、これらの同じメソッドはそれらで動作し続けます。ここのコールバック構文のいずれかが不安定に感じた場合、関数を通して戻るパスは、残りをクリックします。