はじめに
Rubyだと簡単に配列の内容を指定個数、繰り返した配列を作れますが、
javascriptで簡単に短く作る方法はないのか調べてみました。
シンプルな例
ruby
> hash = { a: 1 }
> array = [hash] * 3
=> [{:a=>1}, {:a=>1}, {:a=>1}]
javascript
> var hash = { a: 1 };
> var array = Array(3).fill(hash);
=> [ { a: 1 }, { a: 1 }, { a: 1 } ]
しかし、これだと hash
変数の値に変更を加えると全て反映されてしまいます。
ruby❌
> hash[:a] = 2
> array
=> [{:a=>2}, {:a=>2}, {:a=>2}]
javascript❌
> hash.a = 2;
> array
=> [ { a: 2 }, { a: 2 }, { a: 2 } ]
オブジェクトを複製する
ruby
> hash = { a: 1 }
> array = [hash.dup] * 3
> hash[:a] = 2
> array
=> [{:a=>1}, {:a=>1}, {:a=>1}]
javascript
> var hash = { a: 1 };
> var array = Array(3).fill({ ...hash });
> hash.a = 2;
> array
=> [ { a: 1 }, { a: 1 }, { a: 1 } ]
hash
変数の値に影響されなくなりましたが、配列の一つのオブジェクトに変更を加えると全てに反映されます。
ruby❌
> array[0][:a] = 2
> array
=> [{:a=>2}, {:a=>2}, {:a=>2}]
javascript❌
> array[0].a = 2;
> array
=> [ { a: 2 }, { a: 2 }, { a: 2 } ]
配列の要素一つずつオブジェクトを生成する
ruby✅
> hash = { a: 1 }
> array = Array.new(3) { hash.dup }
> hash[:a] = 2
> array[0][:a] = 3
> array
=> [{:a=>3}, {:a=>1}, {:a=>1}]
javascript✅
> var hash = { a: 1 };
> var array = Array.from({ length: 3 }, () => ({ ...hash }));
> hash.a = 2;
> array[0].a = 3;
> array
=> [ { a: 3 }, { a: 1 }, { a: 1 } ]
Array(3).fill()
等で、なんとかして指定長の配列さえ作れてしまえば、 map
を使っても良いかと思いましたが、
Array.from
の length
プロパティで数値指定できるのがしっくりきました。
Array().fill()
> var array = Array(3).fill();
> array
=> [ undefined, undefined, undefined ]
> array = array.map(() => ({ ...hash }));
> hash.a = 2;
> array[0].a = 3;
> array
=> [ { a: 3 }, { a: 1 }, { a: 1 } ]
最後に
同じ内容を繰り返した配列を作るような状況はあまり無いかと思いますが、後輩に聞かれて焦ったので調べました。
間違い、より良い方法等ございましたらコメント下さい。