diff --git a/files/ja/web/javascript/reference/global_objects/array/fill/index.md b/files/ja/web/javascript/reference/global_objects/array/fill/index.md index e56ca6611f7aa0..0607add5eaba13 100644 --- a/files/ja/web/javascript/reference/global_objects/array/fill/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/fill/index.md @@ -2,31 +2,37 @@ title: Array.prototype.fill() slug: Web/JavaScript/Reference/Global_Objects/Array/fill l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: e01fd6206ce2fad2fe09a485bb2d3ceda53a62de --- {{JSRef}} -**`fill()`** メソッドは、開始位置(既定値は `0`)から終了位置(既定値は `array.length`)までのすべての要素を、静的な値に変更した配列を返します。 +**`fill()`** は {{jsxref("Array")}} インスタンスのメソッドで、インデックスの範囲内にある配列のすべての要素を一定の値に変更します。これは変更した配列を返します。 {{EmbedInteractiveExample("pages/js/array-fill.html")}} ## 構文 -```js -fill(value); -fill(value, start); -fill(value, start, end); +```js-nolint +fill(value) +fill(value, start) +fill(value, start, end) ``` ### 引数 - `value` - - : 配列に設定する値です。 + - : 配列を埋める値。もし `value` がオブジェクトであれば、配列のそれぞれの要素はそのオブジェクトを参照します。 - `start` {{optional_inline}} - - : 開始する位置です。既定値は `0` です。 + - : 埋め始める位置のゼロから始まるインデックスで、[整数に変換されます](/ja/docs/Web/JavaScript/Reference/Global_Objects/Number#整数への変換)。 + - インデックスが負の場合、配列の末尾からさかのぼって数えます。 `start < 0` の場合、 `start + array.length` が使用されます。 + - `start < -array.length` または `start` が省略された場合は `0` が使用されます。 + - `start >= array.length` の場合、埋められるインデックスはありません。 - `end` {{optional_inline}} - - : 終了する位置です。既定値は `arr.length` です。 + - : 埋め終える位置のゼロから始まるインデックスで、[整数に変換されます](/ja/docs/Web/JavaScript/Reference/Global_Objects/Number#整数への変換)。 `fill()` は `end` を含まず、その直前までを埋めます。 + - インデックスが負の場合、配列の末尾からさかのぼって数えます。 `end < 0` の場合、 `end + array.length` が使用されます。 + - `end < -array.length` の場合は `0` が使用されます。 + - `end >= array.length` または `end` が省略された場合、 ### 返値 @@ -34,11 +40,11 @@ fill(value, start, end); ## 解説 -- `start` が負の場合 `array.length + start` として扱われます。 -- `end` が負の場合 `array.length + end` として扱われます。 -- `fill` は意図的に一般化されています。 `this` が `Array` オブジェクトである必要はありません。 -- `fill` は変更を行うメソッドです。配列そのものを変更して返します。コピーを返すのではありません。 -- 最初の引数がオブジェクトの場合、配列の各スロットはそのオブジェクトを参照します。 +`fill()` メソッドは[変更メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#コピーメソッドと変更メソッド)です。これは `this` の長さは変更しませんが、 `this` のコンテンツは変更します。 + +`fill()` メソッドは[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)の空のスロットを、 `value` で埋めます。 + +`every()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。このメソッドは `this` の値に `length` プロパティと整数のキーを持ったプロパティがあることだけを求めます。文字列も配列風のものですが、文字列は不変なので、このメソッドを適用するのは適していません。 > **メモ:** `Array.prototype.fill()` を空の配列に対して使用すると、配列に変更するものがないので何も変更されません。 > 配列を宣言する際に `Array.prototype.fill()` を使用する場合は、スロットを配列に割り当てるようにしてください。 @@ -58,7 +64,6 @@ console.log([1, 2, 3].fill(4, -3, -2)); // [4, 2, 3] console.log([1, 2, 3].fill(4, NaN, NaN)); // [1, 2, 3] console.log([1, 2, 3].fill(4, 3, 5)); // [1, 2, 3] console.log(Array(3).fill(4)); // [4, 4, 4] -console.log([].fill.call({ length: 3 }, 4)); // {0: 4, 1: 4, 2: 4, length: 3} // 配列の各スロットから参照される、単一のオブジェクト。 const arr = Array(3).fill({}); // [{}, {}, {}] @@ -89,6 +94,18 @@ console.log(arr[2][0]); // 1 const tempGirls = Array(5).fill("girl", 0); ``` +配列は最初はインデックスが割り当てられていない[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)であることに注意してください。 `fill()` でこの配列を埋めることができます。 + +### 配列でないオブジェクトに対する fill() の呼び出し + +`fill()` メソッドは `this` の `length` プロパティを読み取り、 `start` から `end` までの各整数キーのプロパティの値を設定します。 + +```js +const arrayLike = { length: 2 }; +console.log(Array.prototype.fill.call(arrayLike, 1)); +// { '0': 1, '1': 1, length: 2 } +``` + ## 仕様書 {{Specifications}} @@ -100,5 +117,6 @@ const tempGirls = Array(5).fill("girl", 0); ## 関連情報 - [`Array.prototype.fill` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)ガイド - {{jsxref("Array")}} - {{jsxref("TypedArray.prototype.fill()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/filter/index.md b/files/ja/web/javascript/reference/global_objects/array/filter/index.md index 143f1829c40006..f052aa1ad7e9c4 100644 --- a/files/ja/web/javascript/reference/global_objects/array/filter/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/filter/index.md @@ -2,51 +2,36 @@ title: Array.prototype.filter() slug: Web/JavaScript/Reference/Global_Objects/Array/filter l10n: - sourceCommit: d0e961d9a7368356b5d26efaaa7191b4f56a425a + sourceCommit: d9e66eca59d82c65166c65e7946332650da8f48f --- {{JSRef}} -**`filter()`** メソッドは、この配列の中から、提供された関数で実装されたテストに合格した要素のみを抽出した[シャローコピー](/ja/docs/Glossary/Shallow_copy)を作成します。 +**`filter()`** は {{jsxref("Array")}} インスタンスのメソッドで、指定された配列の中から指定された関数で実装されているテストに合格した要素だけを抽出した[シャローコピー](/ja/docs/Glossary/Shallow_copy)を作成します。 -{{EmbedInteractiveExample("pages/js/array-filter.html","shorter")}} +{{EmbedInteractiveExample("pages/js/array-filter.html", "shorter")}} ## 構文 ```js-nolint -// アロー関数 -filter((element) => { /* … */ } ) -filter((element, index) => { /* … */ } ) -filter((element, index, array) => { /* … */ } ) - -// コールバック関数 filter(callbackFn) filter(callbackFn, thisArg) - -// インラインコールバック関数 -filter(function(element) { /* … */ }) -filter(function(element, index) { /* … */ }) -filter(function(element, index, array){ /* … */ }) -filter(function(element, index, array) { /* … */ }, thisArg) ``` ### 引数 - `callbackFn` - - : 配列の各要素に対して実行するテスト関数です。この関数が `true` を返した要素は残され、`false` を返した要素は取り除かれます。 - - この関数は以下の引数と共に呼び出されます。 - + - : 配列のそれぞれの要素に対して実行する関数です。この関数は、配列の要素を保持する場合は[真値](/ja/docs/Glossary/Truthy)、保持しない場合は[偽値](/ja/docs/Glossary/Falsy)を返します。この関数は以下の引数で呼び出されます。 - `element` - : 配列内で処理中の現在の要素です。 - `index` - - : 配列内で処理中の現在の要素の位置です。 + - : 配列内で処理中の現在の要素のインデックスです。 - `array` - : `filter()` が呼び出された配列です。 - `thisArg` {{optional_inline}} - - : `callbackFn` を実行するときに `this` として使用する値です。 + - : `callbackFn` を実行する際に `this` として使用される値。[反復可能メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復可能メソッド)を参照してください。 ### 返値 @@ -54,27 +39,25 @@ filter(function(element, index, array) { /* … */ }, thisArg) ## 解説 -`filter()` は、与えられた `callbackFn` 関数を配列の各要素に対して一度ずつ呼び出し、`callbackFn` が [`true` に評価される値](/ja/docs/Glossary/Truthy)を返したすべての要素からなる新しい配列を生成します。 `callbackFn` は値が代入されている配列の添字に対してのみ呼び出されます。つまり、すでに削除された添字や、まだ値が代入されていない添字に対しては呼び出されません。`callbackFn` によるテストに合格しなかった配列要素は単純にスキップされ、新しい配列には含まれないだけです。 +`filter()` メソッドは[反復可能メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復可能メソッド)です。指定された `callbackFn` 関数を配列の各要素に対して一度ずつ呼び出し、 `callbackFn` が[真値](/ja/docs/Glossary/Truthy)を返したすべての要素からなる新しい配列を生成します。 `callbackFn` は値が代入されている配列の添字に対してのみ呼び出されます。 -`callbackFn` は 3 つの引数と共に呼び出されます。 +`callbackFn` は値が割り当てられている配列インデックスに対してのみ呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)の空のスロットに対しては呼び出されません。 -1. 要素の値 -2. 要素の添字 -3. 走査されている配列オブジェクト +`filter()` メソッドは[コピーメソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#コピーメソッドと変更メソッド)です。これは `this` を変更するのではなく、元の配列と同じ要素を格納した[シャローコピー](/ja/docs/Glossary/Shallow_copy)を返します。しかし、 `callbackFn` として指定された関数は配列を変更することができます。ただし、配列の長さは `callbackFn` を最初に呼び出す前に保存されることに注意してください。したがって、 -`filter` に引数 `thisArg` が与えられた場合、そのオブジェクトは `callbackFn` 関数内の `this` 値として使われます。そうでない場合、 `undefined` が `this` 値として使われます。`callbackFn` 関数内の最終的な `this` 値は[関数内の `this` を決定する一般的ルール](/ja/docs/Web/JavaScript/Reference/Operators/this)に従って決められます。 +- `callbackFn` は、 `every()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。 +- 既に処理したインデックスを変更しても、 `callbackFn` が再度呼び出されることはありません。 +- まだ処理していない既存の配列要素が `callbackFn` によって変更された場合、`callbackFn` に渡される値はその要素が取得された時点での値になります。[削除](/ja/docs/Web/JavaScript/Reference/Operators/delete)された要素は処理されません。 -`filter()` は呼び出された配列を変化させません。 +> **警告:** 上記のように進行中の配列に対して変更を行うと、理解しにくいコードになることが多いので、(特別な場合を除いて)避けるのが一般的です。 -`filter()` によって処理される配列要素の範囲は、`callbackFn` が最初に呼び出される前に設定されます。既に訪問した位置にある要素や範囲外のインデックスに割り当てられた要素に対しては、 `callbackFn` は実行されません。既存の配列要素が削除された場合は、同様にそれらの要素は処理されません。 - -> **警告:** 前項で説明したような、参照中の配列の同時進行での変更は(特殊な場合を除いて)普通は避けるべきです。多くの場合、理解しにくいコードになります。 +`filter()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。このメソッドは `this` の値に `length` プロパティと整数のキーを持ったプロパティがあることだけを求めます。 ## 例 ### 小さい値をすべて取り除く -次の例では、`filter()` を使って `10` 未満の値を持つ要素をすべて取り除いた配列を生成します。 +次の例では、`filter()` を使って 10 未満の値を持つ要素をすべて取り除いた配列を生成します。 ```js function isBigEnough(value) { @@ -137,7 +120,7 @@ console.log("Filtered Array\n", arrByID); // Filtered Array // [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }] -console.log("Number of Invalid Entries = ", invalidEntries); +console.log("Number of Invalid Entries =", invalidEntries); // Number of Invalid Entries = 5 ``` @@ -159,12 +142,37 @@ console.log(filterItems(fruits, "ap")); // ['apple', 'grapes'] console.log(filterItems(fruits, "an")); // ['banana', 'mango', 'orange'] ``` +### 疎配列に対する filter() の使用 + +`filter()` は空のスロットをスキップします。 + +```js +console.log([1, , undefined].filter((x) => x === undefined)); // [undefined] +console.log([1, , undefined].filter((x) => x !== 2)); // [1, undefined] +``` + +### 配列でないオブジェクトに対する filter() の呼び出し + +`filter()` メソッドは `this` の `length` プロパティを読み取り、 `length` 未満の非負の整数のキーを持つすべてのプロパティにアクセスします。 + +```js +const arrayLike = { + length: 3, + 0: "a", + 1: "b", + 2: "c", + 3: "a", // length が 3 であるため filter() は無視する +}; +console.log(Array.prototype.filter.call(arrayLike, (x) => x <= "b")); +// [ 'a', 'b' ] +``` + ### 初期の配列への影響(変更、追加、削除) 以下の例は、配列が変更された時の `filter` の動作をテストするものです。 ```js -// Modifying each word +// それぞれの単語を変更 let words = ["spray", "limit", "exuberant", "destruction", "elite", "present"]; const modifiedWords = words.filter((word, index, arr) => { @@ -173,10 +181,10 @@ const modifiedWords = words.filter((word, index, arr) => { }); console.log(modifiedWords); -// Notice there are three words below length 6, but since they've been modified one is returned +// 6 文字未満の語は 3 つあるが、変更されているので 1 つしか返されない // ["spray"] -// Appending new words +// new の単語を追加 words = ["spray", "limit", "exuberant", "destruction", "elite", "present"]; const appendedWords = words.filter((word, index, arr) => { arr.push("new"); @@ -184,10 +192,10 @@ const appendedWords = words.filter((word, index, arr) => { }); console.log(appendedWords); -// Only three fits the condition even though the `words` itself now has a lot more words with character length less than 6 +// `words` 自体には 6 文字未満の単語がたくさん増えたが、条件に合うのは 3 つだけ // ["spray" ,"limit" ,"elite"] -// Deleting words +// 単語の削除 words = ["spray", "limit", "exuberant", "destruction", "elite", "present"]; const deleteWords = words.filter((word, index, arr) => { arr.pop(); @@ -195,7 +203,7 @@ const deleteWords = words.filter((word, index, arr) => { }); console.log(deleteWords); -// Notice 'elite' is not even obtained as it's been popped off 'words' before filter can even get there +// 'elite' はフィルターが取得する前に 'words' から取り出されているので、取得されていないことに注意 // ["spray" ,"limit"] ``` @@ -210,8 +218,10 @@ console.log(deleteWords); ## 関連情報 - [`Array.prototype.filter` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)ガイド - {{jsxref("Array.prototype.forEach()")}} - {{jsxref("Array.prototype.every()")}} +- {{jsxref("Array.prototype.map()")}} - {{jsxref("Array.prototype.some()")}} - {{jsxref("Array.prototype.reduce()")}} -- {{jsxref("Array.prototype.find()")}} +- {{jsxref("TypedArray.prototype.filter()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/find/index.md b/files/ja/web/javascript/reference/global_objects/array/find/index.md index 063a6f4668a304..ada3b1ea3d1e44 100644 --- a/files/ja/web/javascript/reference/global_objects/array/find/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/find/index.md @@ -10,8 +10,8 @@ l10n: **`find()`** は {{jsxref("Array")}} インスタンスのメソッドで、提供されたテスト関数を満たす配列内の最初の要素を返します。 テスト関数を満たす値がない場合は、 {{jsxref("undefined")}} を返します。 -- 配列内で見つかった要素の**添字**が必要な場合は、{{jsxref("Array/findIndex", "findIndex()")}} を使用してください。 -- **値の添字**を検索する必要がある場合は、{{jsxref("Array/indexOf", "indexOf()")}} を使用してください。({{jsxref("Array/findIndex", "findIndex()")}} と似ていますが、それぞれの要素の等価性はテスト関数ではなく値でチェックします。) +- 配列内で見つかった要素の**インデックス**が必要な場合は、{{jsxref("Array/findIndex", "findIndex()")}} を使用してください。 +- **値のインデックス**を検索する必要がある場合は、{{jsxref("Array/indexOf", "indexOf()")}} を使用してください。({{jsxref("Array/findIndex", "findIndex()")}} と似ていますが、それぞれの要素の等価性はテスト関数ではなく値でチェックします。) - 配列内に値が**存在する**かどうかを調べる必要がある場合は、 {{jsxref("Array/includes", "includes()")}} を使用してください。 - 指定したテスト関数を満たす要素があるかどうかを調べる必要がある場合は、 {{jsxref("Array/some", "some()")}} を使用してください。 @@ -31,7 +31,7 @@ find(callbackFn, thisArg) - `element` - : 配列内で現在処理されている要素です。 - `index` - - : 配列内で現在処理されている要素の添字(位置)です。 + - : 配列内で現在処理されている要素のインデックス(位置)です。 - `array` - : `find()` を呼び出した元の配列です。 - `thisArg` {{optional_inline}} @@ -44,9 +44,9 @@ find(callbackFn, thisArg) ## 解説 -`find()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。配列の要素のそれぞれに対して、添字の昇順に一度ずつ `callbackFn` 関数を実行し、`callbackFn` 関数が[真値](/ja/docs/Glossary/Truthy)を返すまで繰り返します。 `find()` はその要素を返し、配列の反復処理を停止します。もし `callbackFn` が真値を返さない場合、 `find()` は {{jsxref("undefined")}} を返します。 +`find()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。配列の要素のそれぞれに対して、インデックスの昇順に一度ずつ `callbackFn` 関数を実行し、`callbackFn` 関数が[真値](/ja/docs/Glossary/Truthy)を返すまで繰り返します。 `find()` はその要素を返し、配列の反復処理を停止します。もし `callbackFn` が真値を返さない場合、 `find()` は {{jsxref("undefined")}} を返します。 -`callbackFn` は、値が割り当てられているものに限らず、配列中の*すべて*の添字に対して呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)では、空のスロットは `undefined` と同じ動作をします。 +`callbackFn` は、値が割り当てられているものに限らず、配列中の*すべて*のインデックスに対して呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)では、空のスロットは `undefined` と同じ動作をします。 `find()` は、呼び出した配列を変更 (mutate) しませんが、`callbackFn` で提供された関数は変更する可能性があります。しかし、配列の長さは最初に `callbackFn` が呼び出される*前に*設定されます。したがって、 @@ -56,7 +56,7 @@ find(callbackFn, thisArg) > **警告:** 上で説明したような同時進行の変更は、理解しにくいコードになることが多いので、(特別な場合を除いて)避けるのが一般的です。 -`find()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#generic_array_methods)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 +`find()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 ## 例 @@ -115,10 +115,10 @@ console.log([4, 5, 8, 12].find(isPrime)); // 5 疎配列の空のスロットは処理され、 `undefined` と同じように扱われます。 ```js -// 添字が 2, 3, 4 の位置に要素がない配列を宣言 +// インデックスが 2, 3, 4 の位置に要素がない配列を宣言 const array = [0, 1, , , , 5, 6]; -// 値が割り当てられているものに限らず、すべての添字を表示 +// 値が割り当てられているものに限らず、すべてのインデックスを表示 array.find((value, index) => { console.log("Visited index", index, "with value", value); }); @@ -130,7 +130,7 @@ array.find((value, index) => { // Visited index 5 with value 5 // Visited index 6 with value 6 -// 削除されたものを含め、すべての添字を表示 +// 削除されたものを含め、すべてのインデックスを表示 array.find((value, index) => { // 最初の反復処理で要素 5 を削除 if (index === 0) { diff --git a/files/ja/web/javascript/reference/global_objects/array/findindex/index.md b/files/ja/web/javascript/reference/global_objects/array/findindex/index.md index c1cfab4f500bed..4e5edaca85a707 100644 --- a/files/ja/web/javascript/reference/global_objects/array/findindex/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/findindex/index.md @@ -2,70 +2,37 @@ title: Array.prototype.findIndex() slug: Web/JavaScript/Reference/Global_Objects/Array/findIndex l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: 5c3c25fd4f2fbd7a5f01727a65c2f70d73f1880a --- {{JSRef}} -**`findIndex()`** メソッドは、配列内の**指定されたテスト関数に合格する**最初の要素の**位置**を返します。テスト関数に合格する要素がない場合を含め、それ以外の場合は `-1` を返します。 +**`findIndex()`** は {{jsxref("Array")}} インスタンスのメソッドで、配列内の指定されたテスト関数に合格する最初の要素のインデックスを返します。 +テスト関数に合格する要素がなかった場合は `-1` を返します。 -{{EmbedInteractiveExample("pages/js/array-findindex.html","shorter")}} +{{jsxref("Array/find", "find()")}} メソッドも参照してください。こちらのメソッドは、配列内で見つかった要素の位置ではなく、値を返します。 -{{jsxref("Array/find", "find()")}} メソッドも参照してください。このメソッドは、配列内で見つかった要素の位置ではなく、**値**を返します。 +{{EmbedInteractiveExample("pages/js/array-findindex.html", "shorter")}} ## 構文 -```js -// アロー関数 -findIndex((element) => { - /* … */ -}); -findIndex((element, index) => { - /* … */ -}); -findIndex((element, index, array) => { - /* … */ -}); - -// コールバック関数 -findIndex(callbackFn); -findIndex(callbackFn, thisArg); - -// インラインコールバック関数 -findIndex(function (element) { - /* … */ -}); -findIndex(function (element, index) { - /* … */ -}); -findIndex(function (element, index, array) { - /* … */ -}); -findIndex(function (element, index, array) { - /* … */ -}, thisArg); +```js-nolint +findIndex(callbackFn) +findIndex(callbackFn, thisArg) ``` ### 引数 - `callbackFn` - - - : 配列内のそれぞれの値に対して実行される関数で、条件を満たす要素が発見されたことを示す `true` が返るまで続けられます。 - - この関数は以下の引数と共に呼び出されます。 - + - : 配列のそれぞれの要素に対して実行する関数です。一致する要素が得られたことを示すには[真値](/ja/docs/Glossary/Truthy)を返し、そうでなければ[偽値](/ja/docs/Glossary/Falsy)を返してください。この関数は以下の引数で呼び出されます。 - `element` - - : 配列内で現在処理されている要素。 + - : 配列内で現在処理されている要素です。 - `index` - - : 配列内で現在処理されている要素の位置。 + - : 配列内で現在処理されている要素のインデックス(位置)です。 - `array` - - : `findIndex()` を呼び出した元の配列。 - - コールバックは適切な要素が見つかったときに、[真値](/ja/docs/Glossary/Truthy)を返す必要があります。 - この要素の位置が `findIndex()` から返されます。 - + - : `findIndex()` を呼び出した元の配列です。 - `thisArg` {{optional_inline}} - - : 任意で、 `callbackFn` を実行する時に `this` として使うオブジェクト。 + - : `callbackFn` 内で `this` として使われるオブジェクトです。[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)を参照してください。 ### 返値 @@ -73,23 +40,19 @@ findIndex(function (element, index, array) { ## 解説 -`findIndex()` メソッドは、配列のそれぞれの位置に対して `callbackFn` を 1 回ずつ呼び出し、 `callbackFn` が{{Glossary("truthy", "真値")}}を返すものを見つけるまで繰り返します。 +`findIndex()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。配列の要素のそれぞれに対して、インデックスの昇順に一度ずつ `callbackFn` 関数を実行し、`callbackFn` 関数が[真値](/ja/docs/Glossary/Truthy)を返すまで繰り返します。 `findIndex()` はその要素を返し、配列の反復処理を停止します。もし `callbackFn` が真値を返さない場合、 `findIndex()` は `-1` を返します。 -そのような要素が見つかったら、 `findIndex()` はすぐにその要素の位置を返します。 `callbackFn` が真値を返すものがなかった場合(または配列の `length` が `0` であった場合)、 `findIndex()` は `-1` を返します。 +`callbackFn` は、値が割り当てられているものに限らず、配列中の*すべて*のインデックスに対して呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)では、空のスロットは `undefined` と同じ動作をします。 -> **メモ:** {{jsxref("Array/some", "some()")}} などの他の配列メソッドとは異なり、 `callbackFn` は値が割り当てられていない位置でも実行されます。 +`findIndex()` は、呼び出した配列を変更 (mutate) しませんが、`callbackFn` で提供された関数は変更する可能性があります。しかし、配列の長さは最初に `callbackFn` が呼び出される*前に*設定されます。したがって、 -`callbackFn` は 3 つの引数で呼び出されます。 +- `callbackFn` は `findIndex()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。 +- 既に訪問した位置を変更しても、 `callbackFn` が再度呼び出されることはありません。 +- まだ訪問していない既存の配列要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値はその要素が取得される時点の値になります。[削除された](/ja/docs/Web/JavaScript/Reference/Operators/delete) 要素は `undefined` であるかのように処理されます。 -1. その要素の値 -2. その要素の位置 -3. 走査されている配列オブジェクト +> **警告:** 上で説明したような同時進行の変更は、理解しにくいコードになることが多いので、(特別な場合を除いて)避けるのが一般的です。 -`thisArg` 引数を `findIndex()` に与えた場合、それぞれの `callbackFn` の呼び出し時に、その与えたオブジェクトが `this` として使用されます。この引数を省略した場合は {{jsxref("undefined")}} になります。 - -`findIndex()` で処理される要素の範囲は、 `callbackFn` が最初に呼び出される前に設定されます。既に処理済みの位置に割り当てられた要素や、その範囲を超えた要素に対しては、 `callbackFn` が実行されません。 `callbackFn` は最初の `findIndex()` の呼び出し以降に配列に追加された要素は処理しません。配列内で未処理の既存の要素が `callbackFn` によって変更された場合、 `callbackFn` へ渡される値は `findIndex()` がその要素の位置を処理する時点での値になります。{{jsxref("Operators/delete", "削除", "", 1)}}された値も処理対象になります。 - -> **警告:** 前項で説明したような、参照中の配列の同時進行での変更は(特殊な場合を除いて)普通は避けるべきです。多くの場合、理解しにくいコードになります。 +`findIndex()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 ## 例 @@ -114,17 +77,29 @@ console.log([4, 6, 8, 9, 12].findIndex(isPrime)); // -1, not found console.log([4, 6, 7, 9, 12].findIndex(isPrime)); // 2 (array[2] is 7) ``` -### アロー関数を使用して位置を検索する +### 疎配列における find() の使用 -次の例では、アロー関数を使用してフルーツの位置を検索しています。 +疎配列で `undefined` を検索することで、空スロットのインデックスを取得することができます。 ```js -const fruits = ["apple", "banana", "cantaloupe", "blueberries", "grapefruit"]; +console.log([1, , 3].findIndex((x) => x === undefined)); // 1 +``` -const index = fruits.findIndex((fruit) => fruit === "blueberries"); +### 配列でないオブジェクトに対する find() の呼び出し -console.log(index); // 3 -console.log(fruits[index]); // blueberries +`findIndex()` メソッドは `this` の `length` プロパティを読み込み、そのキーが `length` よりも小さい非負の整数である各プロパティにアクセスします。 + +```js +const arrayLike = { + length: 3, + "-1": 0.1, // -1 < 0 なので findIndex() 空は無視される + 0: 2, + 1: 7.3, + 2: 4, +}; +console.log( + Array.prototype.findIndex.call(arrayLike, (x) => !Number.isInteger(x)), +); // 1 ``` ## 仕様書 @@ -138,5 +113,11 @@ console.log(fruits[index]); // blueberries ## 関連情報 - [`Array.prototype.findIndex` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} - {{jsxref("Array.prototype.find()")}} +- {{jsxref("Array.prototype.findLast()")}} +- {{jsxref("Array.prototype.findLastIndex()")}} - {{jsxref("Array.prototype.indexOf()")}} +- {{jsxref("Array.prototype.lastIndexOf()")}} +- {{jsxref("TypedArray.prototype.findIndex()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/findlast/index.md b/files/ja/web/javascript/reference/global_objects/array/findlast/index.md index 52252704522708..41a7a85b7628a5 100644 --- a/files/ja/web/javascript/reference/global_objects/array/findlast/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/findlast/index.md @@ -2,17 +2,15 @@ title: Array.prototype.findLast() slug: Web/JavaScript/Reference/Global_Objects/Array/findLast l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: d9e66eca59d82c65166c65e7946332650da8f48f --- {{JSRef}} -**`findLast()`** メソッドは、指定されたテスト関数を満たす配列の最後の要素の値を返します。 +**`findLast()`** は {{jsxref("Array")}} インスタンスのメソッドで、配列を逆順に反復処理し、指定されたテスト関数を満たす最初の要素の値を返します。 テスト関数を満たす要素がない場合は {{jsxref("undefined")}} が返されます。 -{{EmbedInteractiveExample("pages/js/array-findlast.html","shorter")}} - -検索する必要がある場合、以下のメソッドがあります。 +検索を行う場合は以下のメソッドが必要です。 - 一致する最初の要素を得るには、 {{jsxref("Array/find", "find()")}} を使用してください。 - 配列内で一致する最後の位置を得るには、 {{jsxref("Array/findLastIndex", "findLastIndex()")}} を使用してください。 @@ -22,88 +20,48 @@ l10n: こちらも、テスト関数を使用する代わりに、各要素が値と等しいかどうかを調べます。 - 指定されたテスト関数を満たす要素を得るには {{jsxref("Array/some", "some()")}} を使用してください。 -## 構文 - -```js -// アロー関数 -findLast((element) => { - /* … */ -}); -findLast((element, index) => { - /* … */ -}); -findLast((element, index, array) => { - /* … */ -}); +{{EmbedInteractiveExample("pages/js/array-findlast.html", "shorter")}} -// コールバック関数 -findLast(callbackFn); -findLast(callbackFn, thisArg); +## 構文 -// インラインコールバック関数 -findLast(function (element) { - /* … */ -}); -findLast(function (element, index) { - /* … */ -}); -findLast(function (element, index, array) { - /* … */ -}); -findLast(function (element, index, array) { - /* … */ -}, thisArg); +```js-nolint +findLast(callbackFn) +findLast(callbackFn, thisArg) ``` ### 引数 - `callbackFn` - - - : 配列の要素をテストするために使用する関数です。 - - この関数は以下の引数で呼び出されます。 - + - : 配列のそれぞれの要素に対して実行する関数です。一致する要素が得られたことを示すには[真値](/ja/docs/Glossary/Truthy)を返し、そうでなければ[偽値](/ja/docs/Glossary/Falsy)を返してください。この関数は以下の引数で呼び出されます。 - `element` - - : 配列の現在の要素。 + - : 配列内で現在処理されている要素です。 - `index` - - : 配列内の現在の要素の添字(位置)。 + - : 配列内で現在処理されている要素のインデックス(位置)です。 - `array` - - : `findLast()` が呼び出された配列。 - - コールバックは適切な要素が得られたことを示すために、[真値](/ja/docs/Glossary/Truthy)を返さなければなりません。 - この要素の値が `findLast()` によって返されます。 - + - : `findLast()` を呼び出した元の配列です。 - `thisArg` {{optional_inline}} - - : `callbackFn` の実行時に {{jsxref("Operators/this", "this")}} として使用するオブジェクト。 + - : `callbackFn` 内で `this` として使われるオブジェクトです。[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)を参照してください。 ### 返値 -指定されたテスト関数を満たす、配列中の最も大きい添字の値を持つ要素の値。一致する要素が見つからない場合は {{jsxref("undefined")}} となります。 +指定されたテスト関数を満たす、配列中の最も大きいインデックス値を持つ要素の値。一致する要素が見つからない場合は {{jsxref("undefined")}} となります。 ## 解説 -`findLast()` メソッドは `callbackFn` が[真値](/ja/docs/Glossary/Truthy)を返すまで、配列のそれぞれの要素に対して、添字の降順で `callbackFn` 関数を一度ずつ実行します。 -その後、 `findLast()` はその要素の値を返し、配列の反復処理を停止します。 -もし `callbackFn` が真値を返さなかった場合、 `findLast()` は {{jsxref("undefined")}} を返します。 - -`callbackFn` は、値が割り当てられている添字だけでなく、配列のすべての添字に対して呼び出されます。 -これは、代入された値のみを参照するメソッドと比較して、不連続の配列では効率が悪くなることを意味しています。 +`findLast()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。配列の要素のそれぞれに対して、インデックスの降順に一度ずつ `callbackFn` 関数を実行し、`callbackFn` 関数が[真値](/ja/docs/Glossary/Truthy)を返すまで繰り返します。 `findLast()` はその要素を返し、配列の反復処理を停止します。もし `callbackFn` が真値を返さない場合、 `find()` は {{jsxref("undefined")}} を返します。 -`findLast()` に `thisArg` 引数が指定された場合は、 `callbackFn` を呼び出すたびに `this` の値として使用されます。 -指定されなかった場合は、{{jsxref("undefined")}} が使用されます。 +`callbackFn` は、値が割り当てられているものに限らず、配列中の*すべて*のインデックスに対して呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)では、空のスロットは `undefined` と同じ動作をします。 -`findLast()` メソッドは呼び出された配列を変更しませんが、 `callbackFn` に指定された関数は変更することができます。 -`findLast()` が処理する要素は、 `callbackFn` の最初の呼び出しの前に設定されます。 -したがって、 +`findLast()` は、呼び出した配列を変更 (mutate) しませんが、`callbackFn` で提供された関数は変更する可能性があります。しかし、配列の長さは最初に `callbackFn` が呼び出される*前に*設定されます。したがって、 -- `callbackFn` は、 `findLast()` の呼び出しが始まった後に配列に追加された要素に対しては呼び出されません。 -- 既に呼び出されたことのある添字に割り当てられた要素に対して、再び `callbackFn` が呼び出されることはありません。 -- 範囲外の添字に割り当てられた要素に対しては、 `callbackFn` は呼び出されません。 -- 既存の、まだ呼び出されていない配列の要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値は、 `findLast()` がその要素の添字を呼び出したときの値になります。 -- {{jsxref("Operators/delete", "削除", "", 1)}}された要素に対しても呼び出されます。 +- `callbackFn` は `findLast()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。 +- 既に訪問した位置を変更しても、 `callbackFn` が再度呼び出されることはありません。 +- まだ訪問していない既存の配列要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値はその要素が取得される時点の値になります。[削除された](/ja/docs/Web/JavaScript/Reference/Operators/delete) 要素は `undefined` であるかのように処理されます。 > **警告:** 前項で説明したような、参照中の配列の同時進行での変更は(特殊な場合を除いて)普通は避けるべきです。多くの場合、理解しにくいコードになります。 +`findLast()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 + ## 例 ### 要素のプロパティに一致する配列の最後のオブジェクトを探す @@ -147,7 +105,7 @@ console.log(result); ### 配列中の最後の素数を探す -以下の例では、配列の最後の要素で素数を探します(素数がない場合は {{jsxref("undefined")}} を返しています)。 +以下の例では、配列の最後の要素で素数の最後の要素を返します。素数がない場合は {{jsxref("undefined")}} を返しています。 ```js function isPrime(element) { @@ -168,43 +126,59 @@ console.log([4, 5, 7, 8, 9, 11, 12].findLast(isPrime)); // 11 ### 存在しない要素や削除された要素に対しても呼び出される -以下の例では、存在しない要素や削除された要素に対してもコールバックが呼び出され、渡された値が訪問時の値であることを示しています。 +疎配列の空のスロットは処理され、 `undefined` と同じように扱われます。 ```js -// Declare array with no elements at indexes 2, 3, and 4 +// インデックス 2、3、4 に要素がない配列の宣言 const array = [0, 1, , , , 5, 6]; -// Shows all indexes, not just those with assigned values +// 値が割り当てられているインデックスだけでなく、すべてのインデックスを表示 array.findLast((value, index) => { console.log(`Visited index ${index} with value ${value}`); }); - -// Shows all indexes, including deleted +// Visited index 6 with value 6 +// Visited index 5 with value 5 +// Visited index 4 with value undefined +// Visited index 3 with value undefined +// Visited index 2 with value undefined +// Visited index 1 with value 1 +// Visited index 0 with value 0 + +// 削除されたインデックスを含め、すべてのインデックスを表示 array.findLast((value, index) => { // Delete element 5 on first iteration if (index === 6) { console.log(`Deleting array[5] with value ${array[5]}`); delete array[5]; } - // Element 5 is still visited even though deleted + // 要素 5 は削除されたにもかかわらず、処理される console.log(`Visited index ${index} with value ${value}`); }); -// expected output: -// > "Visited index 6 with value 6" -// > "Visited index 5 with value 5" -// > "Visited index 4 with value undefined" -// > "Visited index 3 with value undefined" -// > "Visited index 2 with value undefined" -// > "Visited index 1 with value 1" -// > "Visited index 0 with value 0" -// > "Deleting array[5] with value 5" -// > "Visited index 6 with value 6" -// > "Visited index 5 with value undefined" -// > "Visited index 4 with value undefined" -// > "Visited index 3 with value undefined" -// > "Visited index 2 with value undefined" -// > "Visited index 1 with value 1" -// > "Visited index 0 with value 0" +// Deleting array[5] with value 5 +// Visited index 6 with value 6 +// Visited index 5 with value undefined +// Visited index 4 with value undefined +// Visited index 3 with value undefined +// Visited index 2 with value undefined +// Visited index 1 with value 1 +// Visited index 0 with value 0 +``` + +### 配列でないオブジェクトに対する findLast() の呼び出し + +`findLast()` メソッドは `this` の `length` プロパティを読み込み、次にキーが `length` より小さい非負の整数である各プロパティにアクセスします。 + +```js +const arrayLike = { + length: 3, + 0: 2, + 1: 7.3, + 2: 4, + 3: 3, // length が 3 なので findLast() は無視される +}; +console.log( + Array.prototype.findLast.call(arrayLike, (x) => Number.isInteger(x)), +); // 4 ``` ## 仕様書 @@ -217,9 +191,14 @@ array.findLast((value, index) => { ## 関連情報 -- [`Array.prototype.findLast` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) -- {{jsxref("Array.prototype.findIndex()")}} – 最後の要素を見つけて位置を返す -- {{jsxref("Array.prototype.includes()")}} – 配列内に値が存在するかどうかをテストする -- {{jsxref("Array.prototype.filter()")}} – 一致しない要素をすべて除外する -- {{jsxref("Array.prototype.every()")}} – すべての要素をテストする -- {{jsxref("Array.prototype.some()")}} – 1 つの要素が一致するまでテストする +- [`Array.prototype.findLast` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#array-find-from-last) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} +- {{jsxref("Array.prototype.find()")}} +- {{jsxref("Array.prototype.findIndex()")}} +- {{jsxref("Array.prototype.findLastIndex()")}} +- {{jsxref("Array.prototype.includes()")}} +- {{jsxref("Array.prototype.filter()")}} +- {{jsxref("Array.prototype.every()")}} +- {{jsxref("Array.prototype.some()")}} +- {{jsxref("TypedArray.prototype.findLast()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/findlastindex/index.md b/files/ja/web/javascript/reference/global_objects/array/findlastindex/index.md index defff0d880322d..c9083b3f38ee32 100644 --- a/files/ja/web/javascript/reference/global_objects/array/findlastindex/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/findlastindex/index.md @@ -2,106 +2,64 @@ title: Array.prototype.findLastIndex() slug: Web/JavaScript/Reference/Global_Objects/Array/findLastIndex l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: d9e66eca59d82c65166c65e7946332650da8f48f --- {{JSRef}} -**`findLastIndex()`** メソッドは、指定されたテスト関数を満たす配列の最後の要素の添字を返します。 +**`findLastIndex()`** は {{jsxref("Array")}} のメソッドで、この配列を逆順に反復処理し、指定されたテスト関数を満たす配列の最後の要素のインデックスを返します。 テスト関数を満たす要素がなかった場合は、 -1 を返します。 -{{EmbedInteractiveExample("pages/js/array-findlastindex.html","shorter")}} - {{jsxref("Array/findLast", "findLast()")}} メソッドも参照してください。こちらはテスト関数を満たす最後の要素の(位置ではなく)値を返します。 +{{EmbedInteractiveExample("pages/js/array-findlastindex.html", "shorter")}} + ## 構文 -```js -// アロー関数 -findLastIndex((element) => { - /* … */ -}); -findLastIndex((element, index) => { - /* … */ -}); -findLastIndex((element, index, array) => { - /* … */ -}); - -// コールバック関数 -findLastIndex(callbackFn); -findLastIndex(callbackFn, thisArg); - -// インラインコールバック関数 -findLastIndex(function (element) { - /* … */ -}); -findLastIndex(function (element, index) { - /* … */ -}); -findLastIndex(function (element, index, array) { - /* … */ -}); -findLastIndex(function (element, index, array) { - /* … */ -}, thisArg); +```js-nolint +findLastIndex(callbackFn) +findLastIndex(callbackFn, thisArg) ``` ### 引数 - `callbackFn` - - - : 配列内の要素をテストするのに使用される関数。 - - この関数は以下の引数で呼び出されます。 - + - : 配列のそれぞれの要素に対して実行する関数です。一致する要素が得られたことを示すには[真値](/ja/docs/Glossary/Truthy)を返し、そうでなければ[偽値](/ja/docs/Glossary/Falsy)を返してください。この関数は以下の引数で呼び出されます。 - `element` - - : 配列内で現在処理されている要素。 + - : 配列内で現在処理されている要素です。 - `index` - - : 配列内で現在処理されている要素の位置。 + - : 配列内で現在処理されている要素のインデックス(位置)です。 - `array` - - : `findLastIndex()` を呼び出した元の配列。 - - コールバックは適切な要素が見つかったときに、[真値](/ja/docs/Glossary/Truthy)を返す必要があります。 - この要素の位置が `findLastIndex()` から返されます。 - + - : `findLastIndex()` を呼び出した元の配列です。 - `thisArg` {{optional_inline}} - - : `callbackFn` の実行時に `this` として使用するオブジェクト。 + - : `callbackFn` 内で `this` として使われるオブジェクトです。[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)を参照してください。 ### 返値 -配列内で、テストを満たした最後の(最も大きな)要素の添字。 -それ以外の場合は,一致する要素が見つからなければ -1 となります。 +配列内で、テストを満たした最後の(最も大きな)要素のインデックス。 +それ以外の場合は,一致する要素が見つからなければ `-1` となります。 ## 解説 -`findLastIndex()` メソッドは、配列のそれぞれの要素に対して、添字の降順に一度ずつ `callbackFn` 関数を実行し、 `callbackFn` が[真値](/ja/docs/Glossary/Truthy)を返すまで続けます。 -そして、 `findLastIndex()` がその要素の添字を返し、配列のイテレーターを停止します。 -もし `callbackFn` が真値を返さなかった場合、 `findLastIndex()` は `-1` を返します。 +`findLastIndex()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。配列のそれぞれの要素に対して、インデックスの降順に一度ずつ指定された `callbackFn` 関数を実行し、 `callbackFn` が[真値](/ja/docs/Glossary/Truthy)を返すまで続けます。そして、 `findLastIndex()` がその要素のインデックスを返し、配列のイテレーターを停止します。もし `callbackFn` が真値を返さなかった場合、 `findLastIndex()` は `-1` を返します。 -`callbackFn` は値が割り当てられている要素だけではなく、配列の「すべての」添字に対して呼び出されます。 -すなわち、不連続な配列では、割り当てられた値のみを参照するメソッドと比較して、効率が悪くなります。 +`callbackFn` は値が割り当てられている要素だけではなく、配列の「すべての」インデックスに対して呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#sparse_arrays)で空のスロットは `undefined` と同じ動作をします。 -`thisArg` 引数が `findLastIndex()` に指定された場合、これを `this` の値として `callbackFn` のそれぞれの呼び出しが行われます。 -指定されなかった場合は、 {{jsxref("undefined")}} が使用されます。 +`findLastIndex()` メソッドは呼び出し元の配列を変更しませんが、 `callbackFn` に指定された関数は変更することがあります。ただし、配列の長さは `callbackFn` を最初に呼び出す前に保存されることに注意してください。したがって、 -`findLastIndex()` メソッドは呼び出し元の配列を変更しませんが、 `callbackFn` に指定された関数は変更することがあります。 -`findLastIndex()` が処理する要素は、 `callbackFn` の最初の呼び出しの「前」に設定されます。 -したがって、 - -- `callbackFn` は、 `findLastIndex()` の呼び出しが始まった後に配列に追加された要素に対しては呼び出されません。 -- 既に呼び出されたことのある添字に割り当てられた要素に対して、再び `callbackFn` が呼び出されることはありません。 -- 範囲外の添字に割り当てられた要素に対しては、 `callbackFn` は呼び出されません。 -- 既存の、まだ呼び出されていない配列の要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値は、 `findLastIndex()` がその要素の添字を呼び出したときの値になります。 -- {{jsxref("Operators/delete", "削除", "", 1)}}された要素に対しても呼び出されます。 +- `callbackFn` は `findLastIndex()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。 +- 既に訪問した位置を変更しても、 `callbackFn` が再度呼び出されることはありません。 +- まだ訪問していない既存の配列要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値はその要素が取得される時点の値になります。[削除された](/ja/docs/Web/JavaScript/Reference/Operators/delete) 要素は `undefined` であるかのように処理されます。 > **警告:** 前項で説明したような、参照中の配列の同時進行での変更は(特殊な場合を除いて)普通は避けるべきです。多くの場合、理解しにくいコードになります。 +`findLastIndex()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 + ## 例 ### 配列内の最後の素数の位置を探す -以下の例では、配列の最後の要素が素数である場合の添字を返します。は素数が存在しない場合は `-1` を返します。 +以下の例では、配列の最後の要素が素数である場合のインデックスを返します。素数が存在しない場合は `-1` を返します。 ```js function isPrime(element) { @@ -116,22 +74,33 @@ function isPrime(element) { return true; } -console.log([4, 6, 8, 12].findLast(isPrime)); // undefined, not found -console.log([4, 5, 7, 8, 9, 11, 12].findLast(isPrime)); // 11 +console.log([4, 6, 8, 12].findLastIndex(isPrime)); // -1, not found +console.log([4, 5, 7, 8, 9, 11, 12].findLastIndex(isPrime)); // 5 ``` -### アロー関数を使用した添字の検索 +### 疎配列に対する findLastIndex() の使用 -以下の例では、アロー関数を使用して果物の添字を探します。 -結果は {{jsxref("Array/findIndex", "findIndex()")}} を使用した場合と同じになることに注意してください。 +疎配列から `undefined` を検索し、空のスロットのインデックスを取得することができます。 ```js -const fruits = ["apple", "banana", "cantaloupe", "blueberries", "grapefruit"]; +console.log([1, , 3].findLastIndex((x) => x === undefined)); // 1 +``` + +### 配列でないオブジェクトに対する findLastIndex() の呼び出し -const index = fruits.findLastIndex((fruit) => fruit === "blueberries"); +`findLastIndex()` メソッドは `this` の `length` プロパティを読み込み、次にキーが `length` より小さい非負の整数である各プロパティにアクセスします。 -console.log(index); // 3 -console.log(fruits[index]); // blueberries +```js +const arrayLike = { + length: 3, + 0: 2, + 1: 7.3, + 2: 4, + 3: 3, // length が 3 であるため findLastIndex() から無視される +}; +console.log( + Array.prototype.findLastIndex.call(arrayLike, (x) => Number.isInteger(x)), +); // 2 ``` ## 仕様書 @@ -144,7 +113,12 @@ console.log(fruits[index]); // blueberries ## 関連情報 -- [`Array.prototype.findIndex` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) -- {{jsxref("Array.prototype.findLast()")}} +- [`Array.prototype.findLastIndex` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#array-find-from-last) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} - {{jsxref("Array.prototype.find()")}} +- {{jsxref("Array.prototype.findIndex()")}} +- {{jsxref("Array.prototype.findLast()")}} - {{jsxref("Array.prototype.indexOf()")}} +- {{jsxref("Array.prototype.lastIndexOf()")}} +- {{jsxref("TypedArray.prototype.findLastIndex()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/flat/index.md b/files/ja/web/javascript/reference/global_objects/array/flat/index.md index bf2a732c540694..bf7d5037d317af 100644 --- a/files/ja/web/javascript/reference/global_objects/array/flat/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/flat/index.md @@ -2,115 +2,39 @@ title: Array.prototype.flat() slug: Web/JavaScript/Reference/Global_Objects/Array/flat l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: e01fd6206ce2fad2fe09a485bb2d3ceda53a62de --- {{JSRef}} -**`flat()`** メソッドは、すべてのサブ配列の要素を指定した深さで再帰的に結合した新しい配列を生成します。 +**`flat()`** は {{jsxref("Array")}} インスタンスのメソッドで、すべてのサブ配列の要素を指定した深さで再帰的に結合した新しい配列を生成します。 {{EmbedInteractiveExample("pages/js/array-flat.html")}} ## 構文 -``` -var newArray = arr.flat([depth]); +```js-nolint +flat() +flat(depth) ``` ### 引数 - `depth` {{optional_inline}} - - : ネストされた配列構造で、どの程度の深さをフラット化するか指定する深さレベルです。既定値は 1 です。 + - : ネストされた配列構造で、どの程度の深さをフラット化するか指定する深さレベルです。 + 既定値は 1 です。 ### 返値 サブ配列の要素を結合した新しい配列。 -## 代替手段 - -### reduce と concat - -```js -const arr = [1, 2, [3, 4]]; - -// 単一レベルの配列にする -arr.flat(); -// 次のものと同様 -arr.reduce((acc, val) => acc.concat(val), []); -// [1, 2, 3, 4] +## 解説 -// または、分割代入の構文を使用して -const flattened = (arr) => [].concat(...arr); -``` +`flat()` メソッドは[コピーメソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#コピーメソッドと変更メソッド)です。これは `this` を変更するのではなく、元の配列と同じ要素を格納した[シャローコピー](/ja/docs/Glossary/Shallow_copy)を返します。 -### reduce + concat + isArray + 再帰 +`flat()` メソッドは、フラット化される配列が[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列)の場合、空のスロットを無視します。例えば、 `depth` が 1 の場合、ルート配列と最初の入れ子配列の空のスロットは無視されますが、それ以上の入れ子配列の空のスロットは配列自体に保持されます。 -```js -const arr = [1, 2, [3, 4, [5, 6]]]; - -// reduce と concat の再帰によって深いレベルを平坦化することができる -function flatDeep(arr, d = 1) { - if (!Array.isArray(arr)) { - return arr; - } - return d > 0 - ? arr.reduce((acc, val) => acc.concat(flatDeep(val, d - 1)), []) - : arr.slice(); -} - -flatDeep(arr, Infinity); -// [1, 2, 3, 4, 5, 6] -``` - -### スタックの使用 - -```js -// 再帰を使わずにスタックを使用して平坦化 -// note that depth control is hard/inefficient as we will need to tag EACH value with its own depth -// also possible w/o reversing on shift/unshift, but array OPs on the end tends to be faster -function flatten(input) { - const stack = [...input]; - const res = []; - while (stack.length) { - // pop value from stack - const next = stack.pop(); - if (Array.isArray(next)) { - // push back array items, won't modify the original input - stack.push(...next); - } else { - res.push(next); - } - } - // reverse to restore input order - return res.reverse(); -} - -const arr = [1, 2, [3, 4, [5, 6]]]; -flatten(arr); -// [1, 2, 3, 4, 5, 6] -``` - -### Generator 関数の使用 - -```js -function* flatten(array, depth) { - if (depth === undefined) { - depth = 1; - } - - for (const item of array) { - if (Array.isArray(item) && depth > 0) { - yield* flatten(item, depth - 1); - } else { - yield item; - } - } -} - -const arr = [1, 2, [3, 4, [5, 6]]]; -const flattened = [...flatten(arr, Infinity)]; -// [1, 2, 3, 4, 5, 6] -``` +`flat()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。しかし、その要素を平坦化するには配列でなければなりません。 ## 例 @@ -136,12 +60,35 @@ arr4.flat(Infinity); ### 平坦化と配列の穴 -flat メソッドは配列内の空要素を削除します。 +`flat()` メソッドは配列内の空要素を削除します。 ```js const arr5 = [1, 2, , 4, 5]; -arr5.flat(); -// [1, 2, 4, 5] +console.log(arr5.flat()); // [1, 2, 4, 5] + +const array = [1, , 3, ["a", , "c"]]; +console.log(array.flat()); // [ 1, 3, "a", "c" ] + +const array2 = [1, , 3, ["a", , ["d", , "e"]]]; +console.log(array2.flat()); // [ 1, 3, "a", ["d", empty, "e"] ] +console.log(array2.flat(2)); // [ 1, 3, "a", "d", "e"] +``` + +### 配列でないオブジェクトに対する flat() の呼び出し + +`flat()` メソッドは `this` の `length` プロパティを読み込み、キーが `length` より小さい非負の整数である各プロパティにアクセスします。要素が配列でない場合は、結果に直接追加されます。要素が配列の場合は、引数 `depth` に従って平坦化されます。 + +```js +const arrayLike = { + length: 3, + 0: [1, 2], + // 配列風オブジェクトは平坦化されない + 1: { length: 2, 0: 3, 1: 4 }, + 2: 5, + 3: 3, // length が 3 なので flat() から無視される +}; +console.log(Array.prototype.flat.call(arrayLike)); +// [ 1, 2, { '0': 3, '1': 4, length: 2 }, 5 ] ``` ## 仕様書 @@ -155,8 +102,9 @@ arr5.flat(); ## 関連情報 - [`Array.prototype.flat` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} +- {{jsxref("Array.prototype.concat()")}} - {{jsxref("Array.prototype.flatMap()")}} - {{jsxref("Array.prototype.map()")}} - {{jsxref("Array.prototype.reduce()")}} -- {{jsxref("Array.prototype.concat()")}} -- [A polyfill](https://github.com/behnammodi/polyfill/blob/master/array.polyfill.js) diff --git a/files/ja/web/javascript/reference/global_objects/array/flatmap/index.md b/files/ja/web/javascript/reference/global_objects/array/flatmap/index.md index 53f4a0e5da450a..bcba8a650167c6 100644 --- a/files/ja/web/javascript/reference/global_objects/array/flatmap/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/flatmap/index.md @@ -2,73 +2,46 @@ title: Array.prototype.flatMap() slug: Web/JavaScript/Reference/Global_Objects/Array/flatMap l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: fb85334ffa4a2c88d209b1074909bee0e0abd57a --- {{JSRef}} -**`flatMap()`** メソッドは、最初にマッピング関数を使用してそれぞれの要素をマップした後、結果を新しい配列内にフラット化します。これは、{{jsxref("Array.prototype.map","map()")}} の後に深さ 1 の {{jsxref("Array.prototype.flat","flat()")}} を行うのと同じですが (`arr.map(...args).flat()`)、これら 2 つのメソッドを別々に呼び出すよりもわずかに効率的です。 +**`flatMap()`** は {{jsxref("Array")}} インスタンスのメソッドで、最初にマッピング関数を使用してそれぞれの要素をマップした後、結果を新しい配列内に平坦化します。これは、 {{jsxref("Array/map", "map()")}} の後に深さ 1 の {{jsxref("Array/flat","flat()")}} を行うのと同じですが (`arr.map(...args).flat()`)、これら 2 つのメソッドを別々に呼び出すよりもわずかに効率的です。 -{{EmbedInteractiveExample("pages/js/array-flatmap.html","shorter")}} +{{EmbedInteractiveExample("pages/js/array-flatmap.html", "shorter")}} ## 構文 -```js -// アロー関数 -flatMap((currentValue) => { - /* … */ -}); -flatMap((currentValue, index) => { - /* … */ -}); -flatMap((currentValue, index, array) => { - /* … */ -}); - -// コールバック関数 -flatMap(callbackFn); -flatMap(callbackFn, thisArg); - -// インラインコールバック関数 -flatMap(function (currentValue) { - /* … */ -}); -flatMap(function (currentValue, index) { - /* … */ -}); -flatMap(function (currentValue, index, array) { - /* … */ -}); -flatMap(function (currentValue, index, array) { - /* … */ -}, thisArg); +```js-nolint +flatMap(callbackFn) +flatMap(callbackFn, thisArg) ``` ### 引数 - `callbackFn` - - : 新しい配列の要素を生成する関数。 - - この関数は以下の引数と共に呼び出されます。 - - - `currentValue` - - : 配列で現在処理されている要素です。 + - : 配列のそれぞれの要素に対して実行する関数。この関数は、新しい配列の要素を格納した配列を返すか、新しい配列に追加する 1 つの配列以外の値を返します。この関数は、以下の引数で呼び出されます。 + - `element` + - : 配列で現在処理中の要素です。 - `index` - - : 配列で現在処理されている要素の添字です。 + - : 配列で現在処理中の要素のインデックスです。 - `array` - - : `flatMap` が呼び出された配列です。 + - : `flatMap()` が呼び出された配列です。 - `thisArg` {{optional_inline}} - - : `callbackFn` を実行するときに `this` として使用する値です。 + - : `callbackFn` を実行するときに `this` として使用する値です。[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)を参照してください。 ### 返値 -各要素がコールバック関数の結果であり、深さが 1 にフラット化された新しい配列です。 +各要素がコールバック関数の結果であり、深さが 1 に平坦化された新しい配列です。 ## 解説 -コールバック関数の詳細な説明は {{jsxref("Array.prototype.map()")}} を参照してください。`flatMap` メソッドは、[`map`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) の後に深さ 1 の [`flat`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) を呼び出すのと同じです。 +`flatMap()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。コールバック関数の詳細な説明は {{jsxref("Array.prototype.map()")}} を参照してください。`flatMap()` メソッドは、[`map(callbackFn, thisArg)`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) の後にの [`flat(1)`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) を呼び出すのと同じです。要素ごとに、新しい要素の配列を生成し、できた配列を連結して新しい配列を形成します。 + +`flatMap()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。ただし、 `callbackFn` から返される値は、平坦化する場合は配列でなければなりません。 ### 代替手段 @@ -109,7 +82,7 @@ arr1.flatMap((x) => [[x * 2]]); // [[2], [4], [6], [8]] ``` -上記は map を使用することでも実現できますが、ここでは `flatMap` の使用方法をよりよく示す例を紹介します。 +上記は map を使用することでも実現できますが、ここでは `flatMap()` の使用方法をよりよく示す例を紹介します。 文章のリストから単語のリストを生成してみましょう。 @@ -125,9 +98,12 @@ arr1.flatMap((x) => x.split(" ")); 出力リストの長さは入力リストの長さとは異なる場合があることに注意してください。 -### `map()` のアイテムの追加と削除 +### map() のアイテムの追加と削除 -`flatMap` は、`map` 中にアイテムの追加と削除(アイテムの数を変更)を行う方法として利用できます。つまり、常に*一対一*ではなく、_多くのアイテムを多くのアイテムに_(入力されたアイテムを個別に扱うことで)マップできるようになります。この意味では、 [filter](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) の逆のような働きをします。単純に、アイテムを保持するには 1 要素の配列を返し、アイテムを追加するには複数要素の配列を返し、アイテムを削除するには 0 要素の配列を返します。 +`flatMap` は、`map` 中にアイテムの追加と削除(アイテムの数を変更)を行う方法として利用できます。 +つまり、常に*一対一*ではなく、_多くのアイテムを多くのアイテムに_(入力されたアイテムを個別に扱うことで)マップできるようになります。 +この意味では、 [filter](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) の逆のような働きをします。 +単純に、アイテムを保持するには 1 要素の配列を返し、アイテムを追加するには複数要素の配列を返し、アイテムを削除するには 0 要素の配列を返します。 ```js // 例えば、すべての負の数を取り除き、 @@ -142,7 +118,41 @@ const result = a.flatMap((n) => { } return n % 2 === 0 ? [n] : [n - 1, 1]; }); -// expected output: [4, 1, 4, 20, 16, 1, 18] +console.log(result); // [4, 1, 4, 20, 16, 1, 18] +``` + +### 疎配列に対する flatMap() の使用 + +`map()` は呼び出されず、 `flat()` は返す配列の空のスロットを無視するので、 `callbackFn` は元の配列の空のスロットに対しては呼び出されません。 + +```js +console.log([1, 2, , 4, 5].flatMap((x) => [x, x * 2])); // [1, 2, 2, 4, 4, 8, 5, 10] +console.log([1, 2, 3, 4].flatMap((x) => [, x * 2])); // [2, 4, 6, 8] +``` + +### 配列以外のオブジェクトに対する flatMap() の呼び出し + +`flatMap()` メソッドは `this` の `length` プロパティを読み込み、次にキーが `length` より小さい非負の整数である各プロパティにアクセスします。コールバック関数の返り値が配列でない場合は、常に結果の配列に直接追加されます。 + +```js +const arrayLike = { + length: 3, + 0: 1, + 1: 2, + 2: 3, + 3: 4, // length が 3 であるため flatMap() から無視される +}; +console.log(Array.prototype.flatMap.call(arrayLike, (x) => [x, x * 2])); +// [1, 2, 2, 4, 3, 6] + +// コールバックから返された配列風のオブジェクトは平坦化されない +console.log( + Array.prototype.flatMap.call(arrayLike, (x) => ({ + length: 1, + 0: x, + })), +); +// [ { '0': 1, length: 1 }, { '0': 2, length: 1 }, { '0': 3, length: 1 } ] ``` ## 仕様書 @@ -156,8 +166,9 @@ const result = a.flatMap((n) => { ## 関連情報 - [`Array.prototype.flatMap` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} +- {{jsxref("Array.prototype.concat()")}} - {{jsxref("Array.prototype.flat()")}} - {{jsxref("Array.prototype.map()")}} - {{jsxref("Array.prototype.reduce()")}} -- {{jsxref("Array.prototype.concat()")}} -- [ポリフィル](https://github.com/behnammodi/polyfill/blob/master/array.polyfill.js) diff --git a/files/ja/web/javascript/reference/global_objects/array/foreach/index.md b/files/ja/web/javascript/reference/global_objects/array/foreach/index.md index e0e71d85da731d..9ccfc5a2de788f 100644 --- a/files/ja/web/javascript/reference/global_objects/array/foreach/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/foreach/index.md @@ -2,7 +2,7 @@ title: Array.prototype.forEach() slug: Web/JavaScript/Reference/Global_Objects/Array/forEach l10n: - sourceCommit: 9b38f886d21c5d0a428f58acb20c4d0fc6c2e098 + sourceCommit: fb85334ffa4a2c88d209b1074909bee0e0abd57a --- {{JSRef}} @@ -13,116 +13,70 @@ l10n: ## 構文 -```js -// アロー関数 -forEach((element) => { - /* … */ -}); -forEach((element, index) => { - /* … */ -}); -forEach((element, index, array) => { - /* … */ -}); - -// コールバック関数 -forEach(callbackFn); -forEach(callbackFn, thisArg); - -// インラインコールバック関数 -forEach(function (element) { - /* … */ -}); -forEach(function (element, index) { - /* … */ -}); -forEach(function (element, index, array) { - /* … */ -}); -forEach(function (element, index, array) { - /* … */ -}, thisArg); +```js-nolint +forEach(callbackFn) +forEach(callbackFn, thisArg) ``` ### 引数 - `callbackFn` - - - : 各要素に対して実行されるコールバック関数です。 - - この関数は、以下の引数と共に呼び出されます。 - + - : 配列のそれぞれの要素に対して実行する関数。返値は破棄されます。この関数は以下の引数で呼び出されます。 - `element` - - : 現在処理されている配列の要素です。 + - : 現在処理中の配列の要素です。 - `index` - - : 配列内の `element` の添字です。 + - : 現在処理中の配列の要素のインデックスです。 - `array` - : `forEach()` が呼び出されている配列です。 - - `thisArg` {{optional_inline}} - - : `callbackFn` 内で `this` として使用する値です。 + - : `callbackFn` を実行するときに `this` として使用する値です。[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)を参照してください。 ### 返値 -`undefined` です。 +なし ({{jsxref("undefined")}})。 ## 解説 -`forEach()` は、与えられた関数 `callbackFn` を配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。インデックスプロパティが削除されていたり、初期化されていなかったりした場合は呼び出されません。(不連続な配列については、[下記の例を参照](#初期化されていない値については何もしない(不連続な配列))。) - -`callbackFn` は次の 3 つの引数で呼び出されます。 +`forEach()` メソッドは[反復処理メソッド](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#反復処理メソッド)です。指定された関数 `callbackFn` を配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。 {{jsxref("Array/map", "map()")}} と異なり、 `forEach()` は常に {{jsxref("undefined")}} を返し、連鎖させることはできません。典型的な使用する用途は、チェーンの終わりで副次効果を実行することです。 -1. 要素の値 -2. 要素のインデックス -3. 走査されている配列 +`callbackFn` は値が割り当てられている配列インデックスに対してのみ呼び出されます。[疎配列](/ja/docs/Web/JavaScript/Guide/Indexed_collections#sparse_arrays)で空のスロットに対しては呼び出されません。 -`thisArg` 引数が `forEach()` に与えられると、それがコールバックの `this` 値になります。 -最終的に `callbackFn` から見える `thisArg` の値は、[関数が見る `this` を決める通常のルール](/ja/docs/Web/JavaScript/Reference/Operators/this) に従って決定されます。 +`forEach()` メソッドは呼び出し元の配列を変更しませんが、 `callbackFn` に指定された関数は変更することがあります。ただし、配列の長さは `callbackFn` を最初に呼び出す前に保存されることに注意してください。したがって、 -`forEach()` によって処理される配列要素の範囲は、`callbackFn` が最初に呼び出される前に設定されます。訪問済みの添字、または範囲を外れた添字に割り当てられている要素については `callbackFn` が実行されません。既存の配列要素が変更または削除された場合、`callbackFn` に渡される値は `forEach()` がそれらを参照した時点での値になります。削除された配列要素を参照することはありません。既に参照された配列要素が反復処理の間に(例えば {{jsxref("Array.prototype.shift()", "shift()")}} を使用して)削除された場合、後の要素は飛ばされます。([下記の例を参照してください](#反復処理中の配列の変更)。) +- `callbackFn` は `forEach()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。 +- 既に訪問した位置を変更しても、 `callbackFn` が再度呼び出されることはありません。 +- まだ訪問していない既存の配列要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値はその要素が取得される時点の値になります。[削除](/ja/docs/Web/JavaScript/Reference/Operators/delete)された要素は `undefined` であるかのように処理されます。 > **警告:** 前項で説明したような、参照中の配列の同時進行での変更は(特殊な場合を除いて)普通は避けるべきです。多くの場合、理解しにくいコードになります。 -`forEach()` は配列の各要素に対して `callbackFn` 関数を一度ずつ実行します。{{jsxref("Array.prototype.map()", "map()")}} や {{jsxref("Array.prototype.reduce()", "reduce()")}} と異なり、返値は常に {{jsxref("undefined")}} であり、チェーンできません。チェーンの最後に副作用を生じさせるのが典型的な使用法です。 +`forEach()` メソッドは[汎用的](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#汎用的な配列メソッド)です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。 -`forEach()` は呼び出された配列を変化させません。(ただし `callbackFn` が変化させる可能性があります) +例外を発生する以外の方法で、 `forEach()` ループを止めたり脱出したりする方法はありません。そのような動作を行う場合、 `forEach()` メソッドは適切な方法ではありません。 -> **メモ:** 例外を発生する以外の方法で、`forEach()` ループを止めることはできません。ループ中に中断する必要がある場合、`forEach()` メソッドは適切な方法ではありません。 -> -> 早期終了を行うには下記のような手段が適しています。 -> -> - 単純な [for](/ja/docs/Web/JavaScript/Reference/Statements/for) ループ -> - [for...of](/ja/docs/Web/JavaScript/Reference/Statements/for...of) -> / [for...in](/ja/docs/Web/JavaScript/Reference/Statements/for...in) ループ -> - {{jsxref("Array.prototype.every()")}} -> - {{jsxref("Array.prototype.some()")}} -> - {{jsxref("Array.prototype.find()")}} -> - {{jsxref("Array.prototype.findIndex()")}} -> -> 他の Array のメソッドである {{jsxref("Array.prototype.every()", "every()")}}, {{jsxref("Array.prototype.some()", "some()")}}, {{jsxref("Array.prototype.find()", "find()")}}, {{jsxref("Array.prototype.findIndex()", "findIndex()")}} は、配列の要素を検査する際、truthy の値を返すことで以降の繰り返しが必要であるかどうかを決めます。 +早期終了は [`for`](/ja/docs/Web/JavaScript/Reference/Statements/for), [`for...of`](/ja/docs/Web/JavaScript/Reference/Statements/for...of), [`for...in`](/ja/docs/Web/JavaScript/Reference/Statements/for...in) のようなループ文で行うことができます。また、{{jsxref("Array/every", "every()")}}, {{jsxref("Array/some", "some()")}}, {{jsxref("Array/find", "find()")}}, {{jsxref("Array/findIndex", "findIndex()")}} のような配列メソッドも、それ以上の反復処理が不要な場合は、直ちに反復処理を停止します。 -> **メモ:** forEach は同期関数を期待します。 -> -> `forEach` はプロミスを待ちません。`forEach` のコールバックとしてプロミス (または非同期関数) を使用する場合は、その意味合いを理解しておくようにしてください。 -> -> ```js -> const ratings = [5, 4, 5]; -> let sum = 0; -> -> const sumFunction = async (a, b) => a + b; -> -> ratings.forEach(async (rating) => { -> sum = await sumFunction(sum, rating); -> }); -> -> console.log(sum); -> // 本来期待される出力: 14 -> // 実際の出力: 0 -> ``` +`forEach()` は同期関数を期待します。プロミスを待ちません。`forEach` のコールバックとしてプロミス(または非同期関数)を使用する場合は、その意味合いを理解しておくようにしてください。 + +```js +const ratings = [5, 4, 5]; +let sum = 0; + +const sumFunction = async (a, b) => a + b; + +ratings.forEach(async (rating) => { + sum = await sumFunction(sum, rating); +}); + +console.log(sum); +// 本来期待される出力: 14 +// 実際の出力: 0 +``` + +一連の非同期処理を順次または並列に実行するには、[プロミスの合成](/ja/docs/Web/JavaScript/Guide/Using_promises#合成)を参照してください。 ## 例 -### 初期化されていない値については何もしない(不連続な配列) +### 不連続な配列に対する forEach() の使用 ```js-nolint const arraySparse = [1, 3, /* 空 */, 7]; @@ -215,7 +169,8 @@ console.log(obj.sum); // 16 次のコードは与えられたオブジェクトのコピーを生成します。 -オブジェクトのコピーを作成するには様々な方法があります。以下のものは一つの方法で、`Array.prototype.forEach()` が `Object.*` ユーティリティ関数を使用して、どのように動作するかを説明しています。 +オブジェクトのコピーを作成するには様々な方法があります。 +以下のものは一つの方法で、`Array.prototype.forEach()` が `Object.*` ユーティリティ関数を使用して、どのように動作するかを説明しています。 ```js const copy = (obj) => { @@ -253,9 +208,10 @@ words.forEach((word) => { console.log(words); // ['two', 'three', 'four'] ``` -### 配列の平板化 +### 配列の平坦化 -次の例は学習目的だけのものです。組み込みメソッドを使用して配列を平板化したい場合は、{{jsxref("Array.prototype.flat()")}} を使用することができます。 +次の例は学習目的だけのものです。 +組み込みメソッドを使用して配列を平坦化したい場合は、{{jsxref("Array.prototype.flat()")}} を使用することができます。 ```js const flatten = (arr) => { @@ -275,6 +231,24 @@ const nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]]; console.log(flatten(nested)); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` +### 配列以外のオブジェクトに対する forEach() の呼び出し + +`forEach()` メソッドは `this` の `length` プロパティを読み込み、次にキーが `length` より小さい非負の整数である各プロパティにアクセスします。 + +```js +const arrayLike = { + length: 3, + 0: 2, + 1: 3, + 2: 4, + 3: 5, // length が 3 であるため forEach() からは無視される +}; +Array.prototype.forEach.call(arrayLike, (x) => console.log(x)); +// 2 +// 3 +// 4 +``` + ## 仕様書 {{Specifications}} @@ -286,11 +260,13 @@ console.log(flatten(nested)); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ## 関連情報 - [`Array.prototype.forEach` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド +- {{jsxref("Array")}} - {{jsxref("Array.prototype.find()")}} -- {{jsxref("Array.prototype.findIndex()")}} - {{jsxref("Array.prototype.map()")}} - {{jsxref("Array.prototype.filter()")}} - {{jsxref("Array.prototype.every()")}} - {{jsxref("Array.prototype.some()")}} +- {{jsxref("TypedArray.prototype.forEach()")}} - {{jsxref("Map.prototype.forEach()")}} - {{jsxref("Set.prototype.forEach()")}} diff --git a/files/ja/web/javascript/reference/global_objects/array/from/index.md b/files/ja/web/javascript/reference/global_objects/array/from/index.md index 806d7f4ec42ad9..5b92523a3c1570 100644 --- a/files/ja/web/javascript/reference/global_objects/array/from/index.md +++ b/files/ja/web/javascript/reference/global_objects/array/from/index.md @@ -2,61 +2,35 @@ title: Array.from() slug: Web/JavaScript/Reference/Global_Objects/Array/from l10n: - sourceCommit: 968e6f1f3b6f977a09e116a0ac552459b741eac3 + sourceCommit: fb85334ffa4a2c88d209b1074909bee0e0abd57a --- {{JSRef}} -**`Array.from()`** メソッドは、反復可能オブジェクトや配列風オブジェクトからシャローコピーされた、新しい `Array` インスタンスを生成します。 +**`Array.from()`** 静的メソッドは、[反復可能オブジェクト](/ja/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol)や[配列風オブジェクト](/ja/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects)からシャローコピーされた、新しい `Array` インスタンスを生成します。 -{{EmbedInteractiveExample("pages/js/array-from.html","shorter")}} +{{EmbedInteractiveExample("pages/js/array-from.html", "shorter")}} ## 構文 -```js -// アロー関数 -Array.from(arrayLike, (element) => { - /* … */ -}); -Array.from(arrayLike, (element, index) => { - /* … */ -}); - -// マッピング関数 -Array.from(arrayLike, mapFn); -Array.from(arrayLike, mapFn, thisArg); - -// インラインマッピング関数 -Array.from(arrayLike, function mapFn(element) { - /* … */ -}); -Array.from(arrayLike, function mapFn(element, index) { - /* … */ -}); -Array.from( - arrayLike, - function mapFn(element) { - /* … */ - }, - thisArg, -); -Array.from( - arrayLike, - function mapFn(element, index) { - /* … */ - }, - thisArg, -); +```js-nolint +Array.from(arrayLike) +Array.from(arrayLike, mapFn) +Array.from(arrayLike, mapFn, thisArg) ``` ### 引数 - `arrayLike` - : 配列に変換する反復可能オブジェクトまたは配列風オブジェクト。 -- `mapFn` {{Optional_inline}} - - : 配列のすべての要素に対して呼び出される マッピング関数。 -- `thisArg` {{Optional_inline}} - - : `mapFn` を実行する時に `this` として使用する値。 +- `mapFn` {{optional_inline}} + - : 配列の各要素に対して呼び出す関数です。指定された場合、配列に追加されるすべての値は最初にこの関数に渡され、代わりに `mapFn` の返値が配列に追加されます。この関数は以下の引数で呼び出されます。 + - `element` + - : 配列内で現在処理中の要素です。 + - `index` + - : 配列内で現在処理中の要素のインデックスです。 +- `thisArg` {{optional_inline}} + - : `mapFn` を実行する時に `this` として使用する値です。 ### 返値 @@ -69,15 +43,15 @@ Array.from( - [反復可能オブジェクト](/ja/docs/Web/JavaScript/Reference/Iteration_protocols)({{jsxref("Map")}} や {{jsxref("Set")}} のような要素を取得するオブジェクト) - オブジェクトが反復可能でない場合は、配列風オブジェクト(`length` プロパティおよび添字の付いた要素を持つオブジェクト) -`Array.from()` にはオプションの引数 `mapFn` があります。これにより作成中の配列のすべての要素に対して {{jsxref("Array.prototype.map()", "map()")}} 関数を実行することができます。 +反復可能オブジェクトでも配列風でもない普通のオブジェクトを配列に変換するには(プロパティのキー、値、またはその両方を列挙して) {{jsxref("Object.keys()")}}、{{jsxref("Object.values()")}}、{{jsxref("Object.entries()")}} のいずれかを使用してください。[非同期反復可能オブジェクト](/ja/docs/Web/JavaScript/Reference/Iteration_protocols#非同期イテレーターと非同期反復可能プロトコル)を配列に変換するには、{{jsxref("Array.fromAsync()")}}を使用します。 -より明確に言うと、中間配列を生成しないことを除いて、`Array.from(obj, mapFn, thisArg)` は `Array.from(obj).map(mapFn, thisArg)` と同じ結果です。 _mapFn_ は配列全体ではなく 2 つの引数 (_element_, _index_) のみを取るため、配列は構築途中になります。 +`Array.from()` は疎配列を作成しません。 `arrayLike` オブジェクトのインデックスプロパティが欠けている場合、新しい配列では `undefined` になります。 -> **メモ:** これは、[型付き配列](/ja/docs/Web/JavaScript/Typed_arrays)のような特定の配列のサブクラスでは特に重要です。なぜなら、中間配列の値は適切な型に収まるように切り捨てられている必要があるからです。 +`Array.from()` にはオプションで `mapFn` という引数があり、 {{jsxref("Array/map", "map()")}} と同様に、作成する配列のそれぞれの要素に対して関数を実行することができます。より明確には、`Array.from(obj, mapFn, thisArg)` は `Array.from(obj).map(mapFn, thisArg)` と同じ結果を保有します。ただし、`Array.from(obj).map(mapFn, thisArg)` は中間配列を作成せず、`mapFn` は配列全体を持たずに 2 つの引数 (`element`, `index`) を受け取るだけです。 -`from()` メソッドの `length` プロパティは 1 です。 +> **メモ:** この動作は[型付き配列](/ja/docs/Web/JavaScript/Guide/Typed_arrays)にとってより重要です。なぜなら、中間の配列は適切な型を入力するために必然的に値が切り捨てられるからです。 `Array.from()` は {{jsxref("TypedArray.from()")}} と同じシグネチャを持つために実装します。 -ES2015 では、 [class](/ja/docs/Web/JavaScript/Reference/Classes) 構文により定義済みクラスとユーザー定義クラスの両方をサブクラス化することができます。結果として、`Array.from` のような静的メソッドは `Array` のサブクラスに「継承」され、`Array` ではなくサブクラスのインスタンスを生成します。 `Array.from()` メソッドも汎用的に定義されており、単一の数値の引数を受け入れる任意のコンストラクターに定義することができます。 +`Array.from()` メソッドは汎用ファクトリーメソッドです。例えば、 `Array` のサブクラスが `from()` メソッドを継承した場合、継承した `from()` メソッドは `Array` インスタンスではなく、サブクラスの新しいインスタンスを返します。実際には、新しい配列の長さを表す単一の引数を受け入れるコンストラクター関数を `this` 値として指定することができます。反復可能オブジェクトが `arrayLike` として渡された場合、コンストラクターは引数なしで呼び出されます。配列風のオブジェクトが渡された場合、コンストラクターは配列風オブジェクトの[正規化された長さ](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#length_プロパティの正規化)で呼び出されます。最終的な `length` は反復処理が完了したときに再び設定されます。もし `this` の値がコンストラクター関数でない場合、代わりにプレーンな `Array` コンストラクターが使用されます。 ## 例 @@ -122,7 +96,7 @@ Array.from(mapper.keys()); ```js // DOM 要素のプロパティに基づく配列を作成します。 -const images = document.getElementsByTagName("img"); +const images = document.querySelectorAll("img"); const sources = Array.from(images, (image) => image.src); const insecureSources = sources.filter((link) => link.startsWith("http://")); ``` @@ -165,7 +139,7 @@ const range = (start, stop, step) => range(0, 4, 1); // [0, 1, 2, 3, 4] -// 1..10 の範囲の数値を 2 ごとに生成 +// 1..10 の範囲の数値を 2 ごとに生成 range(1, 10, 2); // [1, 3, 5, 7, 9] @@ -176,6 +150,32 @@ range("A".charCodeAt(0), "Z".charCodeAt(0), 1).map((x) => // ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] ``` +### 配列でないコンストラクターにおける from() の呼び出し + +`from()` メソッドは、新しい配列の長さを表す単一の引数を受け入れるコンストラクター関数で呼び出すことができます。 + +```js +function NotArray(len) { + console.log("NotArray called with length", len); +} + +// 反復可能 +console.log(Array.from.call(NotArray, new Set(["foo", "bar", "baz"]))); +// NotArray を length が undefined のままで呼び出し +// NotArray { '0': 'foo', '1': 'bar', '2': 'baz', length: 3 } + +// 配列風 +console.log(Array.from.call(NotArray, { length: 1, 0: "foo" })); +// NotArray called with length 1 +// NotArray { '0': 'foo', length: 1 } +``` + +`this` の値がコンストラクタでない場合は、プレーンな `Array` オブジェクトを返します。 + +```js +console.log(Array.from.call({}, { length: 1, 0: "foo" })); // [ 'foo' ] +``` + ## 仕様書 {{Specifications}} @@ -187,7 +187,10 @@ range("A".charCodeAt(0), "Z".charCodeAt(0), 1).map((x) => ## 関連情報 - [`Array.from` のポリフィル (`core-js`)](https://github.com/zloirock/core-js#ecmascript-array) +- [インデックス付きコレクション](/ja/docs/Web/JavaScript/Guide/Indexed_collections)のガイド - {{jsxref("Array")}} +- {{jsxref("Array/Array", "Array()")}} - {{jsxref("Array.of()")}} +- {{jsxref("Array.fromAsync()")}} - {{jsxref("Array.prototype.map()")}} - {{jsxref("TypedArray.from()")}}