-
-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(array): Object.groupBy
静的メソッドを追加
#1749
Changes from all commits
324987a
93b3315
84b8c2e
47f5223
7696d24
ff64404
c8c0a04
e41c192
731d9d4
7c9007b
7835c33
a824828
57be123
baa5f42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
v20.11.1 | ||
v22.4.1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,13 +79,13 @@ IssueやPull Requestについては、次のページを参照してください | |
|
||
npm install | ||
|
||
Node.js v20.11.1以上とnpm 10.2.4以上が必要です。 | ||
Node.js v22.4.1以上とnpm 10.8.2以上が必要です。 | ||
|
||
``` | ||
$ node -v | ||
v20.11.1 | ||
v22.4.1 | ||
$ npm -v | ||
10.2.4 | ||
10.8.2 | ||
``` | ||
Comment on lines
-82
to
89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. book.jsonはまた別で更新。テストがNode.js 22じゃないと全てはpassしないので(20でもignoreされるだけで動きはする) |
||
|
||
## Usage | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -978,7 +978,7 @@ console.log(totalValue); // => 6 | |
そのため、できる限り変数を`const`で宣言したい場合には`reduce`メソッドは有用です。 | ||
一方で、`reduce`メソッドは可読性があまりよくないため、コードの意図が伝わりにくいというデメリットもあります。 | ||
|
||
`reduce`メソッドには利点と可読性のトレードオフがありますが、利用する場合は`reduce`メソッドを扱う処理を関数で囲むなど処理の意図がわかるように工夫をする必要があります。 | ||
`reduce`メソッドには利点と可読性のトレードオフがありますが、利用する場合は`reduce`メソッドを扱う処理を関数にするといった処理の意図がわかるように工夫をする必要があります。 | ||
|
||
{{book.console}} | ||
```js | ||
|
@@ -991,6 +991,55 @@ function sum(array) { | |
console.log(sum(array)); // => 6 | ||
``` | ||
|
||
### [ES2024] `Object.groupBy`静的メソッド {#object-group-by} | ||
|
||
`Array.prototype.reduce`メソッドを使うことで、配列から数値やオブジェクトなど任意の値を作成できます。 | ||
|
||
先ほどは配列の合計の数値を計算する例でしたが、配列からオブジェクトを作成することもできます。 | ||
配列からオブジェクトを作成したいユースケースとして、配列の要素を条件によってグループ分けしたいケースがあります。 | ||
たとえば、数値からなる配列の要素を奇数と偶数の配列に分けたい場合などです。 | ||
|
||
`Array.prototype.reduce`メソッドを使って、数値からなる配列を奇数と偶数に分けるコードは次のようになります。 | ||
|
||
{{book.console}} | ||
```js | ||
const array = [1, 2, 3, 4, 5]; | ||
const grouped = array.reduce((accumulator, currentValue) => { | ||
// 2で割った余りが0なら偶数(even)、そうでないなら奇数(odd) | ||
const key = currentValue % 2 === 0 ? "even" : "odd"; | ||
if (!accumulator[key]) { | ||
accumulator[key] = []; | ||
} | ||
// グループ分けしたキーの配列に要素を追加 | ||
accumulator[key].push(currentValue); | ||
return accumulator; | ||
}, {}); | ||
console.log(grouped.even); // => [2, 4] | ||
console.log(grouped.odd); // => [1, 3, 5] | ||
``` | ||
|
||
しかし、`reduce`メソッドは使い方がやや複雜であるため、可能なら避けたほうが読みやすいコードとなりやすいです。 | ||
ES2024では、`Object.groupBy`静的メソッドが追加され、配列からグループ分けしたオブジェクトを作成できるようになっています。 | ||
|
||
`Object.groupBy`静的メソッド[^1]は、第1引数に配列を、第2引数にグループ分けの条件を返すコールバック関数を渡します。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
FootnotesThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。 proposal-array-groupingでもArray限定で始まってたのでそこまで意識してなかったですが、色々考えてみてここではiterableについて触れる必要性はあまりないかなと思いました。 現実的な理由としては、配列以外のiterableを渡すユースケースがあまり思いつかない(setはあるかもしれないが)のと、章の構成的に他のiterableがこの章より前に説明されてるものが配列以外はないことなどがあります。(文字列はあるが実用性がない) iterable対応といった場合にも、無限iteratorには対応してないので、ちょっと中途半端な気がしています。
// infinity iterator
const infinityIterator = function*() {
let i = 0;
while (true) {
yield i++;
}
};
const grouped = Object.groupBy(infinityIterator(), value => {
if (value % 2 === 0) {
return 'even';
}
return 'odd';
});
console.log(grouped); なので、具体的にはArrayとMap/Setを受け付けるという感じになる気がしますが、 おそらくIterator Helpersが入った時にIteratorが本格的に意識される気がするので、その時にiterable関係を章を独立させたり考え直すのがいいんじゃなかなと思ってます。 iterableを扱う同様のものとして 💭 iterableといったときに無限と有限があんまり意識できないので、MDNはリストとか言ったり、コレクションとかいうみたいな整理も合わせて必要そう。iteratorだけで切り出すとちょっと難しい部分かもしれない。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. サンプルコードとしてiterableを受け付けることは省くのが妥当な気はするけど(書籍の目的外になる)、シグネチャの説明として"配列を含むiterableなオブジェクト"てきな表現にするのはありかもしれない。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #1754 で対応しました There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。おっしゃるとおり、現実的にはObject.groupByに渡される値は配列がメインですので、もし言及されるとしても軽く触れる程度で良いと思います。 |
||
第2引数のコールバック関数が返した値をキーとして、配列の要素をグループ分けしたオブジェクトが作成されます。 | ||
|
||
先ほどのコードを`Object.groupBy`静的メソッドを使って書き換えると、次のようになります。 | ||
|
||
{{book.console}} | ||
<!-- doctest:meta:{ "ECMAScript": "2024" } --> | ||
```js | ||
const array = [1, 2, 3, 4, 5]; | ||
const grouped = Object.groupBy(array, (currentValue) => { | ||
// currentValueが偶数なら"even"、そうでないなら"odd"の配列に追加される | ||
return currentValue % 2 === 0 ? "even" : "odd"; | ||
}); | ||
console.log(grouped.even); // => [2, 4] | ||
console.log(grouped.odd); // => [1, 3, 5] | ||
Comment on lines
+1032
to
+1038
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Object.groupByは Object.create(null)を返すのプロパティ同士の比較にした。 |
||
``` | ||
|
||
`Object.groupBy`静的メソッドを使うことで、配列からグループ分けしたオブジェクトを簡潔に作成できます。 | ||
|
||
## [コラム] Array-likeオブジェクト {#array-like} | ||
|
||
配列のように扱えるが配列ではないオブジェクトのことを、**Array-likeオブジェクト**と呼びます。 | ||
|
@@ -1030,7 +1079,7 @@ function myFunc() { | |
myFunc("a", "b", "c"); | ||
``` | ||
|
||
Array-likeオブジェクトは配列のようで配列ではないというもどかしさを持つオブジェクトです。`Array.from`メソッド<sup>[ES2015]</sup>を使うことでArray-likeオブジェクトを配列に変換して扱うことができます。一度配列に変換してしまえばArrayメソッドも利用できます。 | ||
Array-likeオブジェクトは配列のようで配列ではないというもどかしさを持つオブジェクトです。`Array.from`静的メソッド<sup>[ES2015]</sup>を使うことでArray-likeオブジェクトを配列に変換して扱うことができます。一度配列に変換してしまえばArrayメソッドも利用できます。 | ||
|
||
{{book.console}} | ||
```js | ||
|
@@ -1123,3 +1172,5 @@ console.log(versionNames); // => ["ECMAScript 1", "ECMAScript 2", "ECMAScript 3" | |
[Lodash]: https://lodash.com/ "Lodash" | ||
[Immutable.js]: https://immutable-js.com/ "Immutable.js" | ||
[Arrayについてのドキュメント]: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array | ||
|
||
[^1]: `Array.prototype.groupBy`メソッドのようなArrayのメソッドではないのは、同じメソッド名を実装するウェブサイトが多く存在しており後方互換性がなかったためです。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://nodejs.org/en/blog/release/v22.5.1
22.5.0は動かないため。