質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

2回答

348閲覧

javascriptのmapについて(コールバック関数)

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

0グッド

0クリップ

投稿2019/01/16 04:39

const a = [1,2,5,10]; const b = a.map(function(item){ return item * 2; }); console.log(b);//[2, 4, 10, 20]

リターンの部分なのですが、
どこに値を返しているのかイメージできません。
もし、わかりやすく説明できる方がいれば教えて下さい。
なんとなくのイメージだと
↓こんな感じだと思ったのですがundefindでした汗。

class Class { mapp(callback){ callback('name');} } let d = new Class(); let c = d.mapp(function(item){ return item; }); console.log(c);//undefind

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

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

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

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

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

set0gut1

2019/01/16 04:46

callback('name') を return callback('name') にすると undefined にはならないです
退会済みユーザー

退会済みユーザー

2019/01/16 06:04

表示されました。ありがとうございます。
guest

回答2

0

ベストアンサー

Array.prototype.mapの中身はだいたいこのような挙動になっています。

JavaScript

1function map (items, callback) { 2 var results = []; 3 for (var i = 0; i < items.length; i++) { 4 var item = items[i]; 5 var result = callback(item, i, items); 6 results.push(result); 7 } 8 return results; 9} 10 11function add2 (num) { 12 return num + 2; 13} 14console.log(map([1, 2, 3], add2)); // [3, 4, 5] 15console.log([1, 2, 3].map(add2)); // [3, 4, 5] 16 17// ES6仕様 18const amap = (items, callback) => { 19 const results = []; 20 for (let i = 0; i < items.length; i++) { 21 const item = items[i]; 22 const result = callback(item, i, items); 23 results.push(result); 24 } 25 return results; 26} 27 28const aadd2 = it => it + 2; 29console.log(amap([1, 2, 3], aadd2)); // [3, 4, 5] 30console.log([1, 2, 3].map(aadd2)); // [3, 4, 5]

もうまんまこれなので、ゆっくりでも良いので反芻して飲み込んでください。
mapというのは数学用語の写像で、
配列を集合、関数を公式に見立てただけのまんまそれです。

工場でラインに乗って流れてきたモノを上からぎゅーってプレス加工して大量生産するのもmapと言うそうですよ。

リターンの部分なのですが、どこに値を返しているのかイメージできません。

result = callback(item, i, items);の部分に着目してください。
mapは配列の全ての要素に同じ関数を適用し、その戻り値を使って新しい配列を作っています。
ですので、戻り値を返さない関数だとundefinedの配列になってしまいます。

JavaScript

1var result = [1, 2, 3].map(function (it) { 2 it + 2; // 四則演算を行うが何もreturnしていない 3}) 4 5// ES6仕様 6const aresult = [1, 2, 3].map(it => { 7 it + 2; // 四則演算を行うが何もreturnしていない 8}); 9console.log(aresult); // [undefined, undefined, undefined]

投稿2019/01/16 04:50

編集2019/01/16 06:14
miyabi-sun

総合スコア21158

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

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

退会済みユーザー

退会済みユーザー

2019/01/16 06:03

おそらく、これ以上ないくらい わかりやすく説明して下さっていると思うのですが、 今の私には質問のレベルが高すぎました汗。 関数式とかアロー関数の書き方すら慣れていない初心者なので、 何がわからないのかも分からないレベルです。 もう少し基礎の部分を学習してから、もう一度、 回答して頂いた内容を見直そうと思います。
miyabi-sun

2019/01/16 06:19

ES5のコードを併記しました。 JavaScriptは関数を「変数に代入」「関数実行時の引数に設定」という事が出来る珍しい言語です。 それ利用して「配列の各要素にこれ(関数)実行した結果で新しい配列作ってよ」みたいな事が出来るんですね。 この辺は関数型プログラミング的な考え方で、中級者以上向きの内容になってきます。 興味があるなら下記の本とRamda.jsというライブラリを勉強してみてください。 https://book.impress.co.jp/books/1115101137
退会済みユーザー

退会済みユーザー

2019/01/16 06:27

ありがとうございます。 回答して頂いたコードを自分で書きながら、 じっくり見直したいと思います。
miyabi-sun

2019/01/16 06:32

そうですね、コードのあちこちにconsole.logを仕込みながら動作を見てみるのが一番だと思います。
退会済みユーザー

退会済みユーザー

2019/01/16 07:27

わかりかけてきました。ゆっくり頑張ります。ありがとごいました。
退会済みユーザー

退会済みユーザー

2019/01/16 09:12

何度も読み返してconsole.logを使い倒してやっと理解できました..。ありがとうございます。難しい><
退会済みユーザー

退会済みユーザー

2019/01/16 13:48

[1, 2, 5, 10].map(add2) すいません↑最後のこの部分がわかりませんでした。 map(add2) ↑この部分で関数を呼んでいますよね。 引数のitemsがないのですが..↓ function map (items, callback) ちょっとよくわからなかったです。
miyabi-sun

2019/01/16 14:12 編集

ああ、説明不足でしたね。 まずmapというプロトタイプメソッドの詳細は、 MDNのサイトのArray.prototype.mapを読んでください。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map 実際のArray.prototype.mapのメソッドでは、引数はコールバック関数の1つだけです。 何故なら、メソッドの場合はthisが値そのものに変化するから指定する必要がありません。 `[1, 2, 5, 10].map(fn)`を実行するということは、itemsの部分は`[1, 2, 5, 10]`に決まってるでしょという理屈です。 だから引数はコールバック関数の一つだけで済むのです。 私が回答文で作った`function map (items, callback) {}`の関数は、引数が2つです。 そうしないと何の配列使えば良いかわからないでしょ? その気になればもっと厳密に本物らしく書けますが、 大量のおまじないが必要だったり実行&検証が面倒になります。 なので学習に邪魔になると判断したので引数を2個のクローン的存在の関数を用意する方針で妥協しました。 これが本物のArray.prototype.mapと私の作ったmap関数の大きな違いです。
退会済みユーザー

退会済みユーザー

2019/01/16 14:39

thisというのは[]←ですよね?それが値そのものになるという意味がわかりませんでした。MDNも説明している内容がチンプンカンプンです。やはり中級者にならないと難しいのかもしれませんね。
退会済みユーザー

退会済みユーザー

2019/01/16 14:42

今ドットインストールというプログラミング学習サイトで学んでいるのですが、 とりあえずは、↓これはこういうものだということで丸覚えするしかないようです。 const a = [1,2,5,10]; const b = a.map(function(item){ return item * 2; }); console.log(b);//[2, 4, 10, 20]
miyabi-sun

2019/01/16 14:50

> thisというのは[]←ですよね? 違います。 `[1, 2, 5, 10].map(fn)`で発火させた場合、 `[1, 2, 5, 10]`という4つの数値が詰まった配列がthisになります。 そして1行目で`var items = this`を追加すると、 私の作ったmap関数の挙動に合流します。 後は`for (var i = 0; i < items.length; i++) {`でループさせるだけです。
退会済みユーザー

退会済みユーザー

2019/01/16 14:56

thisが勝手に第一引数になるということでしょうか?
guest

0

最初のコード例を、リターンが分かりそうな感じに書きかえてみました。

javascript

1const mapping = function(ar, func) { 2 let ret = []; 3 for(let i = 0; i < ar.length ; i++) { 4 ret.push(func(ar[i])); // ここで受けてる 5 } 6 return ret; 7} 8const double = function( a) {return a * 2;} //ここでのリターンを↑ 9 10const a = [1,2,5,10]; 11const b = mapping(a, double);

もっと手前のはなしをしたほうがいいのかと思うのでポエムをかきます

エクセルは使ったことありますか?なければgoogleスプレッドシートはありますか(こちら無料なので使ってみてください)?

ABCD
12510
=A1*2=B1*2=C1*2=D1*2

こういうのを想像してください(エクセルになじみがなかったら↑のとおり入れてください)
A2:D2にかいてるのはfunction(a) { return a * 2; }みたいなやつです。
mapによるいわゆる射影/写像という処理は、1行目の配列を2行目の状態にするものです。
jsでmapがcallback(関数の実体)をもらうというのは、excelみたいに、意味的に同じことを何回も入力(コピペ)しなくても、要素に順に適用していってくれるということです。
なので、「何にリターンしているか」という当初の質問については、やや不正確ですが、mapで得る結果配列のなかで、処理する対象となる要素のindex番目と同じ(配列上の)位置にリターンしている、という感じですかね(イメージ先行の説明をしています)
→上の例だとB2の関数は、B2セルにリターンしています。

投稿2019/01/16 04:57

編集2019/01/16 06:37
papinianus

総合スコア12705

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

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

退会済みユーザー

退会済みユーザー

2019/01/16 06:03

私には質問のレベルが高すぎました汗。 関数式とかアロー関数の書き方すら慣れていない初心者なので、 何がわからないのかも分からないレベルです。 もう少し基礎の部分を学習してから、もう一度、 回答して頂いた内容を見直そうと思います。
papinianus

2019/01/16 06:28

アローなんてfunction(){return}の糖衣構文(省略して楽に書ける方法)でしかないので、手強いという認識が手強いだけです。 単純にfunctionにかきかえました。が、悩んでいることにたいして、これは本質じゃないです。
退会済みユーザー

退会済みユーザー

2019/01/16 07:07 編集

ありがとうございます。書き換えて下さったので、回答して下さったコードは無事に読み解けました。あとは、私が質問したコードとどう繋がるのか、考え中です汗。
papinianus

2019/01/16 07:15

質問の1つ目のコードブロックと同じものを書いたつもりです。 私の回答は一旦おいて、miyabi-sun様の`function map`を読みとくことが近道だと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問