質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

4回答

5284閲覧

JavaScriptで二次元配列の値をランダムに並び替え

sika

総合スコア52

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

1クリップ

投稿2017/06/21 00:42

Javascript

1var array_A = [100, 105, 200, 306, 505]; 2var array_B = ["A", "B", "C", "D", "E"]; 3 4var array_BOX = [ 5 array_A , 6 array_B 7];

2つの配列「array_A 」、「array_B 」を新規配列「array_BOX 」に格納して二次元配列化した物の値の並びをランダムに替えたいです。

その際に現時点での配列の順番の対になる値(一次元の[0]である"100"と二次元の[0]である"A")はランダムに並び替えた後もセットとして扱いたいため、

一次元と二次元の値の対関係はそのままで配列の値を並び替えを行える方法のご教授をお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kanimaru

2017/06/21 00:53

array_Aとarray_Bは情報が紐づいている者同士があるにもかかわらず、配列でなければならない制約があり、データ構造は変えられないということでしょうか?
sika

2017/06/21 01:01

最初はarray_Aの値をキーとしてarray_Bを代入する連想化を試みたのですが、できなかったため上記の形となっております。最終的にはランダムで並び替えられた後にループでarray_Aの値と一致した要素にarray_Bの値を出力できれば良いです。
guest

回答4

0

ベストアンサー

二次元配列

配列のシャッフルには Fisher–Yates shuffle を使用しています。

JavaScript

1function arrayShuffle (array) { 2 var k, t, len; 3 4 len = array.length; 5 6 if (len < 2) { 7 return array; 8 } 9 10 while (len) { 11 k = Math.floor(Math.random() * len--); 12 t = array[k]; 13 array[k] = array[len]; 14 array[len] = t; 15 } 16 17 return array; 18} 19 20var array_A = [100, 105, 200, 306, 505]; 21var array_B = ["A", "B", "C", "D", "E"]; 22var array_AB = []; 23 24for (var i = 0, len = array_A.length; i < len; ++i) { 25 array_AB.push([array_A[i], array_B[i]]); 26} 27 28arrayShuffle(array_AB); 29console.log(JSON.stringify(array_AB));

new Map

最初はarray_Aの値をキーとしてarray_Bを代入する連想化を試みたのですが、できなかったため上記の形となっております。

オブジェクト初期化子のキー/プロパティ値には順番の概念がない為、不可能ですが、new Map ならば可能です。

JavaScript

1function arrayShuffle (array) { 2 var k, t, len; 3 4 len = array.length; 5 6 if (len < 2) { 7 return array; 8 } 9 10 while (len) { 11 k = Math.floor(Math.random() * len--); 12 t = array[k]; 13 array[k] = array[len]; 14 array[len] = t; 15 } 16 17 return array; 18} 19 20var array_A = [100, 105, 200, 306, 505]; 21var array_B = ["A", "B", "C", "D", "E"]; 22var array_AB = []; 23 24for (var i = 0, len = array_A.length; i < len; ++i) { 25 array_AB.push([array_A[i], array_B[i]]); 26} 27 28arrayShuffle(array_AB); 29 30var map = new Map(array_AB); 31console.log(JSON.stringify([...map.entries()]));

先の二次元配列のコードに new Map を付け加えただけのコードです。
キー、値の列挙は Map#entries 以外にも Map#forEach もあるので、配列と同じ感覚で扱えます。

Re: sika さん

投稿2017/06/21 01:34

編集2017/06/21 01:54
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sika

2017/06/21 10:28

ご回答ありがとうございます。 アルゴリズムの詳細なども重ねて感謝致します。 arrayShuffle ()内での値が二つ未満の場合の処理といった細かな例外処理もちゃんと考慮されており 本案件としては自分的にはコードの流れとして理想的な物でした。
guest

0

1つのデータ構造として扱った方がいいです。
場合によっては、下記オブジェクト形式よりもクラス化するのも考慮されたほうがいいかもしれません。

javascript

1// データ形式の見直し 2var array_A = [100, 105, 200, 306, 505]; 3var array_B = ["A", "B", "C", "D", "E"]; 4// 5var list = [ 6 { 7 dataA:100, 8 dataB:"A" 9 }, 10 11 { 12 dataA:105, 13 dataB:"B" 14 }, 15 16 { 17 dataA:200, 18 dataB:"C" 19 }, 20 { 21 dataA:306, 22 dataB:"D" 23 }, 24 25 { 26 dataA:505, 27 dataB:"E" 28 } 29]; 30 31shuffle(list); 32 33// シャッフル関数定義 34function shuffle(array) { 35 var n = array.length, t, i; 36 while (n) { 37 i = Math.floor(Math.random() * n--); 38 t = array[n]; 39 array[n] = array[i]; 40 array[i] = t; 41 } 42 return array; 43} 44

####追記
シャッフルについては、think49さんが仰っている「 Fisher–Yates shuffle 」を利用しています。

投稿2017/06/21 01:09

編集2017/06/21 02:36
kanimaru

総合スコア1013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sika

2017/06/21 10:20

ご回答ありがとうございます。 何かしらループ処理を加えないと連想化できないと思っておりました。 シャッフル専用functionは今後も活用させていただきます。
guest

0

こういう組み合わせで管理してはいけないのでしょうか?

javascript

1var a = [100, 105, 200, 306, 505]; 2var b = ["A", "B", "C", "D", "E"]; 3var c = []; 4a.forEach(function(i,j){ 5 c.push({a:i,b:b[j]}); 6}); 7console.log(c); 8

投稿2017/06/21 01:08

yambejp

総合スコア114769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2017/06/21 05:14 編集

この回答はなぜマイナス評価が付いているのでしょうか。 初めは二次元配列ではないから(質問の要件を満たしていない)かと思いましたが、二次元配列ではない他の回答にはマイナス評価がついてないので、マイナス評価の理由が理解できません。 あえて指摘するならば、Array#forEach は Array#map にするとスマートな気がしますが、コード自体は期待通りに動作するのでマイナス評価をつける程ではないように思えます。 とりあえず、プラス評価を付けて打ち消しておきます。 マイナス評価を入れた方へ。理由をコメントで指摘頂けると有難いです。
sika

2017/06/21 10:17

ご回答ありがとうございます。 当方にもマイナス評価の意はわかりかねますが、高評価を足させていただきました。 他回答者様と同様にmap関数の使い方としては良い例題になりました。
guest

0

var a = [100, 105, 200, 306, 505]; var b = ["A", "B", "C", "D", "E"]; var c = a.map(function (value, index) { return [a[index], b[index]]; }) .sort(function (a, b) { // 簡易のランダム入れ替え return Math.random() - .5; }); console.log(c);

修正前のコード

var a = [100, 105, 200, 306, 505]; var b = ["A", "B", "C", "D", "E"]; var c = a.map(function (value, index) { return index; }) .sort(function (a, b) { // 簡易のランダム入れ替え return Math.random() - .5; }) .map(function (value) { return [a[value], b[value]]; }); console.log(c);

投稿2017/06/21 01:26

編集2017/06/21 01:57
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sika

2017/06/21 10:32

ご回答ありがとうございます。 一番スマートなコードという印象を受けましたので、今後の記述の参考にさせていただきたいと思います。 "Array.sortを使ったシャッフルはかなり偏る" 同じランダム処理でも精度の差が出るのですね。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問