ionicを試す 11日目 配列(object)の罠(その2)
前回はピザのトッピング注文をイメージしたMenuとOrderの2つの配列を表にして、各メニューにチェックを入れると簡単な一行のコードで、Order配列並びにテーブルの表示にチェックの反映が出来たことを確認しました。
------------------------------------------
this.Order.push(this.Menu[index]);
------------------------------------------
これは、Menu配列のindexで示される要素を、Order配列の末尾に追加しなさいと言う命令です。
例えば index = 3 ならば以下の連想配列がセットされます。(配列の指標は0から数えます)
---------------------------------------------------------------
{ val: 'トマトソース', category_id: '01', category_name: 'ソース', sub_id: '01', isChecked: false },
---------------------------------------------------------------
ある配列を別な配列の中身をコピーしたい時、直感的に正しそうにも思えるこのコードですが、良くある(しかも原因究明に手間取ることがある)間違いです。
コピーには『コピー元とは別なもの』と言う大前提があります。
漢字の"大"と書いて有る紙をコピーして、元の紙の漢字に点を振って"犬"と言う漢字にしたところでコピーした紙の漢字が"犬"になることは無いですよね?
しかし、上のソースコードの場合、"this.Menu[index]"のvalを 'トマトソース'から'トマトジュース'に変えると、this.Orderに入った最後の配列のvalも'トマトジュース'になります。
これは何故か?
端折って説明すると、"this.Order.push(this.Menu[index]);"と言うのは、中のデータを移す(コピーする)のではなく、コンピュータのメモリー内の位置を移しています。
現実の例にたとえてみます
・ある料理サイトの33ページに『ひよこ豆のカレー』が載っています。
・AさんがBさんに明日このサイトの33ページの料理を作ってと頼みます。
・サイトの管理人が33ページの料理を『サバの味噌煮』に変更します。
・翌日BさんはAさんに『サバの味噌煮』を出しました。
例えはわかっていただけたでしょうか?
とりあえず、配列や連想配列などをコピーするときは注意が必要という事だけは覚えておいてください。
目標のゲームブックアプリでは、配列や連想配列のコピーが必要になるはずですので。
さて、大きな問題点(他にも有りますが)をご理解いただいたかもしれませんが、プログラミングに置いては検証と改善は大事ですので、最後に何が起きるかという事の確認と次にどう変更するか確認して、今回は終わりにしたいと思います。
1.メニューのチェックボックスをオン・オフさせるとオーダーの項目が際限なく増える
(今回は1アイテムは一度だけオーダーできることにしたい)
2.オーダーの項目のチェックボックスとメニューのチェックボックスが連動している
(今回指摘の問題)
3.生地が複数選べるのはおかしい。ソースも一つのみ選択にしたい
4.メニューは並び順になっているのにオーダーの順番がバラバラ
5.オーダー側のチェックを外すとオーダーからアイテムが削除され、メニューのチェックも外したい
6.出来れば生地やソース、トッピングなどのカテゴリー別に並べたい
次回は、上記の問題を見て修正していきたいと思います。
(今回はソースコードの変更がありませんので、この回のソースコードのページはありません。)




