単純なことなんですが、最近うっかり踏みそうになったプチ地雷からのクイズ?です。
突然ですが
何が表示されるでしょうか?
const array2Gen = xs =>
function*(){ yield* xs; }();
const a = [0,1,2];
const g =array2Gen( a );
for(let i of a.keys() ){
a[i] = undefined;
console.log(g.next().value);
};
配列をジェネレータにして、順番に配列の要素の値を変更しながらジェネレータを呼んで表示させるということです。
こんなこと普通はしないでしょうけど。
答は:
undefined
undefined
undefined
です。
const で配列を宣言しても、配列の要素は変更できるのでしたね。ある意味、当然の結果です。
でも場合によっては、ジェネレータにした時点で中味が固定されて、もう変ってほしくないと思うんじゃないでしょうか?
0 1 2
が返ってきてほしいなあ...
うけとった配列をコピーして使う
これはどうでしょう。何が表示されるでしょうか?
const array2Gen = xs =>
function*(){
const ys = [...xs];
yield* ys;
}();
const a = [0,1,2];
const g =array2Gen( a );
for(let i of a.keys() ){
a[i] = undefined;
console.log(g.next().value);
};
受け取った配列 xs を[...xs]で浅いコピーをしてからジェネレータにしています。
これで xs が変更されても大丈夫なはずです。
が、実行してみると...
undefined
1
2
あれ?一回目だけ変更されてる。なぜでしょう?
説明できます?
ともかく、このやりかたでは不十分です。別のやりかたを考えましょう。
コピーしてから渡す
今度はどうでしょう。何が表示されるでしょうか?
const array2Gen = xs =>
function*(){ yield* xs; }();
const a = [0,1,2];
const g = array2Gen( [...a] );
for(let i of a.keys() ){
a[i] = undefined;
console.log(g.next().value);
};
今度は const g = array2Gen( [...a] );
で浅いコピーをしてから関数に渡しています。
結果は?:
0
1
2
やったー!やっとできたー
まとめ
- 何でできたんだろう? 説明できる?
- いつもコピーしたほうがいい? どんなときにコピーするべき?
- 配列だけ? 他に気をつけたほうがいいモノは?
- 浅いコピーで大丈夫? どうやって見分ける?
- やった方がいいことは? 逆にやらない方がいいことは?
- ほかに気付いたこと? 何でも
...というようなクイズ? なんですが、何かお役に立つ内容でしたでしょうか?