0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JS】ランダムシャッフルした配列を格納した多次元配列を作る

Posted at

いきなりですが問題です。

以下のような処理を実装する際、どんな風に実装しますか?
・A,B,C,Dという文字列を含む配列を含む多次元配列を作る
・多次元配列中の二次元配列要素(ABCD)の順序は、1次元要素ことにバラバラである

やりがちなパターン

コードで書くと、以下のような感じで書く方が多いんじゃないでしょうか。

const list = [1, 2, 3, 4];
const result = [];

for (let i=0; i < 10; i++) {
    const item = list.sort(() => 0.5 - Math.random());
    result.push(item);
}
console.log(result);

しかし、実際にやってみると、これでは冒頭の条件を満たせていません。

// 以下、上記コードを実行した結果
(10) [Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4)]
0: (4) [4, 2, 3, 1]
1: (4) [4, 2, 3, 1]
2: (4) [4, 2, 3, 1]
3: (4) [4, 2, 3, 1]
4: (4) [4, 2, 3, 1]
// 以下略

pushした配列の二次元配列の順序が、同じになってしまっています。
itemをconsole.logで出力するとわかりますが、ループごとでランダムシャッフルされています。

正解

const list = [1, 2, 3, 4];
const result = [];

for (let i=0; i < 10; i++) {
    const item = list.sort(() => 0.5 - Math.random());
    result.push(item.concat());
}
console.log(result);

↑のようにpush時にconcat()を追加することで1配列要素ごとに内部の要素がバラバラば配列を作ることができます。

(10) [Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4)]
0: (4) [4, 2, 1, 3]
1: (4) [3, 1, 2, 4]
2: (4) [4, 2, 1, 3]
3: (4) [4, 2, 1, 3]
4: (4) [3, 4, 2, 1]

なぜconcat()を足す必要があるのかというと、pushメソッドでは配列は参照渡しで要素が追加されるからです。

pushメソッドの参照渡しについて

参照渡しとは「関数へ変数の値を記憶しているメモリ領域を渡す」ということです。
これに対して値渡し(関数へ変数の値を渡し、変数の記憶領域はそのまま)というのがあります。

参照渡しについてご存知の方はこのまま読み進めてもらうとして、
分かりやすく示したgifがvue3リファレンスページにあったので、よく分からないという方はイメージを掴むためにチェックするといいかも↓
Vu3リファレンス:ref によるリアクティブな変数

push()が参照渡しであるということは、
forループで毎回個別に作成していたつもりだった配列(item)は、list内に追加済の配列要素でもあるという状態だっため、
新しい配列を返却するconcat()を使ってあげる必要があるのでした。

参照渡し・値渡しになるかは引数の型次第

配列の他にも、Object,クラスをpushに渡した場合も参照渡しになります。
こちらも必要に応じて新しいObject,インスタンスをpush()に渡すなどの対応をするようにしましょう。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?