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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

Q&A

5回答

699閲覧

ループ処理中に新しく配列を作りたい(全ての配列の内容が最後の値に上書きされる)

moge56

総合スコア4

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

0グッド

1クリップ

投稿2020/02/17 08:23

前提・実現したいこと

ループ処理中に新しく配列作成をしたいのですが、どうやっても最後の配列の値で構成された配列になってしまいます。
理想の結果の内容になるためにはどうしたらいいかアドバイスをお願いします。

該当のソースコード

const kanas = [ {name: 'ま', id: 'ma'}, {name: 'み', id: 'mi'} ] const kanaRooms = [ {label: '', owner_id: '', admin_id: 2}, {label: '', owner_id: '', admin_id: 3} ] const moge = [] kanas.forEach(function(val) { console.log('val:' + JSON.stringify(val)) const r = Array.from(kanaRooms) console.log('r:' + JSON.stringify(r)) r.forEach(function(val2) { const insert = val2 insert.label = val.name insert.owner_id = val.id moge.push(insert) }) }) console.log(moge)

上記の結果

> "val:{"name":"ま","id":"ma"}" > "r:[{"label":"","owner_id":"","admin_id":2},{"label":"","owner_id":"","admin_id":3}]" > "val:{"name":"み","id":"mi"}" > "r:[{"label":"ま","owner_id":"ma","admin_id":2},{"label":"ま","owner_id":"ma","admin_id":3}]" > Array [Object { label: "み", owner_id: "mi", admin_id: 2 }, Object { label: "み", owner_id: "mi", admin_id: 3 }, Object { label: "み", owner_id: "mi", admin_id: 2 }, Object { label: "み", owner_id: "mi", admin_id: 3 }]

理想の結果

> "val:{"name":"ま","id":"ma"}" > "r:[{"label":"","owner_id":"","admin_id":2},{"label":"","owner_id":"","admin_id":3}]" > "val:{"name":"み","id":"mi"}" > "r:[{"label":"ま","owner_id":"ma","admin_id":2},{"label":"ま","owner_id":"ma","admin_id":3}]" > Array [Object { label: "ま", owner_id: "ma", admin_id: 2 }, Object { label: "ま", owner_id: "ma", admin_id: 3 }, Object { label: "み", owner_id: "mi", admin_id: 2 }, Object { label: "み", owner_id: "mi", admin_id: 3 }]

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

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

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

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

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

guest

回答5

0

JavaScriptに於ける配列・オブジェクトは参照の値渡しで、
メモリ空間上に実体があり、それをこちょこちょ操作する感じになるので
しっかりコピーを取りつつ作業していかなければなりません。

値を受けるという目的の為にforEachを利用するのは非推奨で、
mapを使いつつ引数への束縛を利用して値をかき集めつつ、
新しいオブジェクトを作って新配列へ投げ込むという手法が良いでしょう。

下記のコードはkanasを起点にkanas.mapを行い、
その中で更にkanaRooms.mapを行って二次元配列を作りました。
最終的には一次元配列で欲しいので.reduce((arr, it) => [...arr, ...it])というイディオムで1次元配列に固め直して完了です。

まぁまぁ綺麗に仕上がったと思います。

js

1const kanas = [ 2 {name: 'ま', id: 'ma'}, 3 {name: 'み', id: 'mi'} 4] 5const kanaRooms = [ 6 {label: '', owner_id: '', admin_id: 2}, 7 {label: '', owner_id: '', admin_id: 3} 8] 9 10const moge = kanas.map( 11 ({name: label, id: owner_id}) => kanaRooms.map( 12 ({admin_id}) => ({label, owner_id, admin_id}) 13 ) 14).reduce((arr, it) => [...arr, ...it]) 15 16console.log(JSON.stringify(moge, null, 2))

結果

JSON

1[ 2 { 3 "label": "ま", 4 "owner_id": "ma", 5 "admin_id": 2 6 }, 7 { 8 "label": "ま", 9 "owner_id": "ma", 10 "admin_id": 3 11 }, 12 { 13 "label": "み", 14 "owner_id": "mi", 15 "admin_id": 2 16 }, 17 { 18 "label": "み", 19 "owner_id": "mi", 20 "admin_id": 3 21 } 22]

投稿2020/02/17 10:06

miyabi-sun

総合スコア21194

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

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

0

こんなかんじでしょうか?

投稿2020/02/17 08:57

yambejp

総合スコア116443

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

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

yambejp

2020/02/17 08:57

const moge = [] kanas.forEach(function(val) { kanaRooms.forEach(function(val2) { var label = val.name; var owner_id = val.id; var admin_id = val2.admin_id; var insert={label,owner_id,admin_id}; moge.push(insert); }); }); console.log(moge) </script>
guest

0

const insert = val2はコピーではないので、その後のinsert.label = val.nameなどが元のオブジェクトにも影響してしまいます。

const insert = {...val2};のようにオブジェクトを再作成する方法が考えられます。

投稿2020/02/17 08:27

maisumakun

総合スコア145930

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

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

0

JavaScriptのreduceメソッドを使うと、シンプルに書けてわかりやすいかなと思いました。
Array.prototype.reduce() - JavaScript _ MDN

js

1const kanas = [ 2 {name: 'ま', id: 'ma'}, 3 {name: 'み', id: 'mi'} 4] 5 6const moge = kanas.reduce((res, kana) => { 7 res.push( 8 { label: kana.name, owner_id: kana.id, admin_id: 2 }, 9 { label: kana.name, owner_id: kana.id, admin_id: 3 } 10 ) 11 return res 12}, []) 13 14console.log(moge); 15 16=> 17[ 18 {label: "ま", owner_id: "ma", admin_id: 2}, 19 {label: "ま", owner_id: "ma", admin_id: 3}, 20 {label: "み", owner_id: "mi", admin_id: 2}, 21 {label: "み", owner_id: "mi", admin_id: 3}, 22] 23

サンプルコード

投稿2020/02/17 08:36

shgtkshruch

総合スコア665

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

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

0

こんにちは

参考までに、一案挙げておきます。

はじめに、配列kanasの要素 kana と、配列kanaRoomsの要素 room とをマージした、ひとつの新しいオブジェクトを返す、以下のような関数を作っておくと見通しがよくなると思います。

javascript

1const merge = (kana, room) => ( 2 { ...room, label: kana.name, owner_id: kana.id } 3)

上記を使って、以下によって、目的とする配列が得られます。

javascript

1const moge = kanas.map(k => kanaRooms.map(r => merge(k, r))).flat()

投稿2020/02/17 12:40

編集2020/02/17 18:26
jun68ykt

総合スコア9058

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問