回答編集履歴

3

補足説明追加

2018/12/07 08:42

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -154,6 +154,8 @@
154
154
 
155
155
  回答文に上がっている解決策はこのシャローコピーやディープコピーの手法です。
156
156
 
157
+ (この手法はどちらもちゃんとGASで使える事を確認しています)
158
+
157
159
 
158
160
 
159
161
  - `JSON.parse(JSON.stringify(...))`: 簡易的なディープコピー
@@ -172,7 +174,7 @@
172
174
 
173
175
  一撃で行けると思ったのですが、どうもGASはJavaScript1.6ベースでできており、
174
176
 
175
- ECMAScript5や6の便利機能はほぼ使えなよう
177
+ ECMAScript6の便利機能は全滅、5も動作が怪し、注意してください
176
178
 
177
179
 
178
180
 
@@ -192,6 +194,8 @@
192
194
 
193
195
  それに頼れないとなると一気に微妙化しますが、こんな感じで配列作る関数を用意して動作させることになります。
194
196
 
197
+ 下記のコードは調査済みで動作します…が、`array.slice()`の方が明らかに筋が良いですね。参考までにどうぞ。
198
+
195
199
 
196
200
 
197
201
  ```JavaScript

2

回避策を記載

2018/12/07 08:42

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -166,34 +166,62 @@
166
166
 
167
167
 
168
168
 
169
- 【おまけ】
170
-
171
- まぁ、n個の要素を持つ配列ならイディオム覚えれば1行ですね。
172
-
173
-
174
-
175
- ```
176
-
177
- n = 11;
178
-
179
- // 全て0埋めしたn個の配列
180
-
181
- console.log(Array(n).fill(0));
182
-
183
- // (11) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
184
-
185
- var maze = Array(n).fill(0).map(() => Array(n).fill(0));
186
-
187
- console.log(maze);
188
-
189
- // (11) [Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11)]
190
-
191
- ```
192
-
193
-
194
-
195
- `Array(n).fill(0)`自体が0埋めされたn個の配列を新しく作るというイディオムであり、
196
-
197
- [Array.prototype.map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)は冒頭に「その結果からなる新しい配列を生成します。」と書いてあるように、
198
-
199
- 新しい配列を作っているので質問文の問題は解消された状態になっています。
169
+ 【おまけ】【修正版】関数作ってワンライナーで頑張る
170
+
171
+
172
+
173
+ 一撃で行けると思ったのですが、どうもGASはJavaScript1.6ベースでできており、
174
+
175
+ ECMAScript5や6の便利機能はほぼ使えないようです。
176
+
177
+
178
+
179
+ 参考サイト
180
+
181
+
182
+
183
+ - [What functions do Arrays in Google Apps Script support?](https://stackoverflow.com/questions/39317252/what-functions-do-arrays-in-google-apps-script-support)
184
+
185
+ - [Basic JavaScript features](https://developers.google.com/apps-script/guides/services/#basic_javascript_features)
186
+
187
+ - [JavaScript 1.6 の新機能 - MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/New_in_JavaScript/1.6)
188
+
189
+
190
+
191
+ そもそも配列の要素を一気につくるイディオムがES6に頼る事になるので、
192
+
193
+ それに頼れないとなると一気に微妙化しますが、こんな感じで配列作る関数を用意して動作させることになります。
194
+
195
+
196
+
197
+ ```JavaScript
198
+
199
+ function myFunction() {
200
+
201
+ var n = 11;
202
+
203
+ var array = function (num) {
204
+
205
+ var arr = [];
206
+
207
+ for (var i = 0; i < num; i++) {
208
+
209
+ arr.push(0);
210
+
211
+ }
212
+
213
+ return arr;
214
+
215
+ }
216
+
217
+ var maze = array(n).map(function () { return array(n); });
218
+
219
+ Logger.log(maze);
220
+
221
+ }
222
+
223
+
224
+
225
+ // [18-12-07 17:36:31:549 JST] [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
226
+
227
+ ```

1

おまけ追加

2018/12/07 08:37

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -30,11 +30,19 @@
30
30
 
31
31
 
32
32
 
33
- JavaScriptの世界では、`{name: "hoge"}`というオブジェクトや、`[1, 2, 3]`という配列を変数に代入した時、変数は「アドレス番地の参照」格納されます。
33
+ JavaScriptの世界では、`{name: "hoge"}`というオブジェクトや、`[1, 2, 3]`という配列を宣言した時、初めてメモリ空間上オブジェクト/配列生成されます。
34
+
35
+ 変数や引数として使う時は全て「メモリ空間のアドレス番地」でやりとりされます(参照やポインタ等と表現されます)
36
+
37
+ 変数に代入された時、目には見えませんしとりだせませんが、オブジェクト/配列の実体ではなく、アドレス番地という数値が代入されていると考えてください。
38
+
39
+
34
40
 
35
41
  `[1, 2, 3] === [1, 2, 3]`の結果が`false`になるのは、比較演算子でオブジェクトや配列を比較した場合、配列そのものではなく、「アドレス番地」での比較になります。
36
42
 
43
+ 1行内に配列宣言が2個ありますので、メモリ空間上に配列2個作られ、それぞれのアドレス番地が帰って来ます。
44
+
37
- メモリ空間上に配列2個作れば別々のアドレス番地2個が払い出されので一致しというカラクリす。
45
+ 々のアドレス番地は当然異な比較結果も`false`にというカラクリになっています。
38
46
 
39
47
 
40
48
 
@@ -86,13 +94,53 @@
86
94
 
87
95
 
88
96
 
89
- 質問文のコードはメモリ空間上にmazeとarrayのコピー11個、計12個の配列が存在して欲しいのだと思いますが、
97
+ 理想はメモリ空間上にmazeとarrayのコピー11個、計12個の配列が存在して`maze`の中身は`[array1, array2, array3 ...]`という風になって欲しいはずですが、
90
98
 
91
- 実際にはmazeとarray1個ずつ、計2個の配列しか存在していない事になり
99
+ 実際にはmazeとarray計2個の配列しか存在していません
100
+
101
+ そりゃarrayの値を1個弄ったら全部変化するよね……という訳で、そのコードは欠陥となるわけです。
92
102
 
93
103
 
94
104
 
105
+ 配列は基本的に宣言したタイミングで作られるので、
106
+
107
+ 素直に解決するなら多重ループに変更してこういったコードになるでしょう。
108
+
109
+
110
+
111
+ ```JavaScript
112
+
113
+ function main (n) {
114
+
115
+ n = 11;
116
+
117
+ var maze = [];
118
+
119
+ for (var i = 0; i < n; i++) {
120
+
121
+ // ループの中で新しい配列を作って育てる
122
+
123
+ var array = [];
124
+
125
+ for (var j = 0; j < n; j++) {
126
+
127
+ array.push(0);
128
+
129
+ }
130
+
131
+ maze.push(array);
132
+
133
+ }
134
+
135
+ }
136
+
137
+ ```
138
+
139
+
140
+
141
+ ですが、ループやif文のネストって理解が難しくなるのでできれば避けたいですよね。
142
+
95
- なのでarrayの複製をメモリ空間上に作るテクニック必要となます。
143
+ そういった時に、メモリ空間上に配列の複製をってしまう手法
96
144
 
97
145
  これをシャローコピーやディープコピーと呼びます。
98
146
 
@@ -111,3 +159,41 @@
111
159
  - `JSON.parse(JSON.stringify(...))`: 簡易的なディープコピー
112
160
 
113
161
  - `array.slice()`: スマートなシャローコピー
162
+
163
+
164
+
165
+ ---
166
+
167
+
168
+
169
+ 【おまけ】
170
+
171
+ まぁ、n個の要素を持つ配列ならイディオム覚えれば1行ですね。
172
+
173
+
174
+
175
+ ```
176
+
177
+ n = 11;
178
+
179
+ // 全て0埋めしたn個の配列
180
+
181
+ console.log(Array(n).fill(0));
182
+
183
+ // (11) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
184
+
185
+ var maze = Array(n).fill(0).map(() => Array(n).fill(0));
186
+
187
+ console.log(maze);
188
+
189
+ // (11) [Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11), Array(11)]
190
+
191
+ ```
192
+
193
+
194
+
195
+ `Array(n).fill(0)`自体が0埋めされたn個の配列を新しく作るというイディオムであり、
196
+
197
+ [Array.prototype.map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)は冒頭に「その結果からなる新しい配列を生成します。」と書いてあるように、
198
+
199
+ 新しい配列を作っているので質問文の問題は解消された状態になっています。