🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1082閲覧

Javascriptのreduceとfindを組み合わせた際の処理について

ryuiti

総合スコア1

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/01/13 09:05

前提・実現したいこと

Javascriptを使ってデータ集計を行っており、reduceやfindを組み合わせた効率的な処理の理解をしたいです。

他サイトを参考にコードをくみ上げたのですが、良く処理を理解できず。
reduceはreturnしたものをどんどん積算していく処理の認識です。
しかし下記コードを動かしたところ、elはreturnしていないのですが、bushoの中にelで計算した結果が入っております。
これはどういう動きをしているのでしょうか。

※以下のサイトを参考にしました。
[https://qiita.com/zaburo/items/fc8f74d144d73b7d70b6]
・応用-GroupBy的な
を参照

該当のソースコード

window.getData = function(data,year){ var busho = data.reduce(function (result, current) { if(current.nendo == year){ var el = result.find(function (p) { return p.futanbusho === current.futanbusho }); if (el) { el.goukei += Number(current.goukei); } else { result.push({ nendo:current.nendo, futanbusho:current.futanbusho, goukei:current.goukei }); } } return result; }, []); return busho; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

[]がinitialValueとして渡されていて、それがresultに入っているものにpushをしているので値が入ります。

【Array.prototype.reduce() - JavaScript | MDN】
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

initialValue Optional

callback の最初の呼び出しの最初の引数として使用する値。initialValue が与えられなかった場合、配列の最初の要素がアキュムレーターの初期値として使用され、currentValue としてスキップされます。

投稿2021/01/13 09:20

kei344

総合スコア69596

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryuiti

2021/01/13 11:47 編集

早速の回答ありがとうございます。 pushでresultに入れていることは理解しました。 私のコードですと、pushでcurrentを入れている認識です。 if(el)の中の処理で、elはreturnもpushもしていないのですが、この計算結果が最終的にresultにも反映されています。それがどうしても理解できないのですが、わかりますでしょうか?
kei344

2021/01/13 12:51

質問文を読み込めていませんでした、すみません。 elは有る場合オブジェクトなので、書き換えることが可能です。 var o1 = [{a:0},{a:1}]; var o2 = o1.find(function (p){return p.a === 0;}); o2 .a = 2; console.log(o1 );
papinianus

2021/01/13 14:00

失敬。 el は result から find したオブジェクトですよね。で (el を含む) result の全体を return しているのですから、accumulator が更新され続けることに違和感ないと思いませんか?
ryuiti

2021/01/14 00:21

kei344さん、papinianusさん ご回答ありがとうございます。 お二人から頂いた内容を見て、理解できたような気がします。 私は result.find で条件に合致した内容が el に渡される際の挙動が、 値のコピーだと思っていたのですが、そうではなく条件に合致した部分の参照が入っているということですよね?(言葉が不正確かもしれませんが。。。) (kei344さんに記載いただいたコードで言うと、var o1 = [{a:0},{a:1}]; の {a:0}への参照が find により o2 に格納される) そのため、その後 o2 の値を弄ると、元であるo1の値も修正される。 上記の理解で合っていますでしょうか?
papinianus

2021/01/14 00:33 編集

ベーシックには値を返します。 > https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find > find() メソッドは、提供されたテスト関数を満たす配列内の 最初の要素 の 値 を返します。 find したものが object であるとき "値" が何を指しているのか、という問題かと。 -- const array1 = [5, 12, 8, 130, 44]; const array2 = [{a:1},{a:2}]; let found1 = array1.find(element => element > 100); found1++; console.log(array1); let found2 = array2.find(element => element.a > 1); found2.a++; console.log(array2); -- は -- > Array [5, 12, 8, 130, 44] > Array [Object { a: 1 }, Object { a: 3 }] -- このような出力になります。
ryuiti

2021/01/14 12:12

papinianusさん 回答ありがとうございます。 自分で頂いたコードを動かしてみて納得できました。 頂いたリンク先の説明の「要素の値を返す」という言葉をうまく飲み込めなかったのですが、 頂いたコードの2パターンの違いから理解できたと思います。 found1では説明通り最初尾要素の値を返している(=コピーしている)。そのため更新してもarray1には影響なし。 found2ではオブジェクト内の一致した要素のアドレス的なものを返している(=同じところを見ている)。そのため、found2を更新すると結果としてarray2も更新したことになる) 改めてお二方とも、お忙しいところご丁寧にご回答いただき、本当にありがとうございました。 また機会ございましたら、その際はよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問