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

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

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

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

Q&A

解決済

3回答

729閲覧

配列に配列をpushした後に計算処理を行いたい

id_masao

総合スコア7

JavaScript

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

0グッド

0クリップ

投稿2017/12/12 06:58

###前提・実現したいこと
配列で複数の数値を管理して、インクリメントや書き換え等の処理を行いたい
のですが、書き換え後の配列が思ったような結果が出ないので質問させていただきたいです。

エラー内容
・配列をpushした配列内の一部を変更すると、想定外の部分まで同じ変更がされてしまう。

###該当のソースコード

javascript

1 test=[] 2 deta=[1,1] 3 test.push(deta) 4 test.push(deta) 5 test[0][1]=2 6 alert(test) 7 //希望イメージ [[1,2],[1,1]] 8 //現実の結果 [[1,2],[1,2]]

###試したこと
pushしていないデータで試した場合想定外の処理は行われなかったため、pushに原因があるのだと思っているのですがよくわかっていません。

javascript

1 //サブテスト 2 test=[[1,1],[1,1]] 3 test[0][1]=2 4 alert(test) 5 //希望イメージ [[1,2],[1,1]] 6 //現実の結果 [[1,2],[1,1]]

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

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

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

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

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

guest

回答3

0

detaの中を見てみると、そこも変更されているのが分かると思います。
pushは引数のオブジェクトをコピーせずにArrayに追加しますので、「同じオブジェクト」になります。

わかりやすい例:

JavaScript

1a = [1,2] 2b = a // 同じオブジェクト 3a[0] = 99 4alert(b[0]) //=> 99

あなたの期待通りにするには、「同じオブジェクト」でなく、「同じ中身を持つ新たなオブジェクト」を用意してやる必要があります。

JavaScript

1 test=[] 2 deta=[1,1] 3 test.push(deta.slice()) 4 test.push(deta.slice()) 5 test[0][1]=2 6 alert(test)

と、一重のArrayであればslice()で出来ます。二重以上だと駄目ですが。

投稿2017/12/12 07:25

otn

総合スコア84538

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

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

id_masao

2017/12/12 07:35

分かりやすい例・対処法ありがとうございます。 slice()いれてみたら本当にできました。 簡易に導入する事ができそうです、ありがとうございます。
guest

0

ベストアンサー

javascitpではArrayを始めとする一般のオブジェクトは参照としてあつかわれます。

dataに入っているのは配列ですが、これを2回pushすると同一の配列実体への参照がpushされます。そのためtestの0番目、1番目は同一の配列実体を参照することになりますので、

test[0][1]=2
test[1][1]=2

のどちらも同じ場所を更新するという意味になります。それぞれを異なる実体にしたいならオブジェクトをコピーして、それをpushしなければなりません。

オブジェクトのコピーの方法には結構バリエーションがあり、浅いコピーや深いコピーの違い、用いるライブラリーなどそれだけでも一つの記事が書けるほどではないかと思います。それはそれで研究してみるとよいと思いますが、例えばjQueryの$.extend()などはよく見る方法だと思います。

投稿2017/12/12 07:12

KSwordOfHaste

総合スコア18394

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

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

id_masao

2017/12/12 07:28

ありがとうございます。 例としてあげて頂いた「$.extend()」を利用したら希望の結果を出力する事ができました。
KSwordOfHaste

2017/12/12 08:10

オブジェクトが要素でない単純なArrayならotnさん回答のようにsliceの方が適切だと思いました。{ a: 1, b: 2}みたいなObjectだと$.extend()がいいのかも知れませんが。
guest

0

javascript

1 test=[] 2 deta=[1,1] 3 var extend_deta=[] 4 $.extend(extend_deta, deta); 5 test.push(deta) 6 test.push(extend_deta) 7 test[0][1]=2 8 alert(test) 9 //希望イメージ [[1,2],[1,1]] 10 //現実の結果 [[1,2],[1,1]]

頂いた回答を元に修正しました。
ありがとうございます。

投稿2017/12/12 07:31

id_masao

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問