- ベストアンサー
JavaScript テーブルデータ:シャッフル関数の修正方法
- JavaScriptのテーブルデータをシャッフルする際、列のシャッフルがされていないという不具合があります。これを修正するには、シャッフル関数内で列のインデックスをランダムに選び、行のデータを入れ替える処理を追加する必要があります。
- 具体的には、シャッフル関数のforループ内で、列のインデックスをランダムに選び、行のデータを入れ替える処理を行います。これにより、テーブル内の全てのTDの内容がシャッフルされるようになります。
- 修正後のシャッフル関数を実装するためには、まずテーブルの各行のデータを取得し、そのデータをシャッフルします。そして、シャッフルされたデータを元のテーブルに戻して表示するようにします。これにより、テーブル内のセルデータがランダムに並び替えられるようになります。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
んま、ループ作成2行、実ソース3行しかない。。 超短い?サンプルなので、拡張性については「しらん」(投げやりw) 今回、こちらのサンプルで一番覚えてほしいのが、 拡散式ソートをシャッフルに使ってる所でしょうね。 12345 ↑ この位置をどっか行け! ↑ この位置をどっか行け! ↑ この位置をどっか行け! と繰り返しているやり方です。 概念としては、元々のソースと同じです。 ただ、コピーインスタンスを作らず、それ自体で ソートを行うので、実変数メモリへのラベル張り替えだけが発生して 実際のデータが変化していないので、ガベージャー的にもロスが少ないですね。 変数名 ラベル 実データ 変数A → 001番地にあるよ! → 001番地のデータ 変数B → 002番地にあるよ! → 002番地のデータ これを、 変数A → 002番地にあるよ! → 001番地のデータ 変数B → 001番地にあるよ! → 002番地のデータ としてるだけなので、クローン不要で、実際のデータも変化していないが、 ラベルだけが変わるから、結果、変数から見たら値が変わったよね? というやり方で、作成しています。 (そこまでまったく誰も求めてないでしょうけど)(だめか~) ってことで!次回また、面白いネタお待ちしてま~す!ではでは
その他の回答 (5)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>具体的なコードをご教示ください。 >よろしくお願いいたします。 Array.prototype.shuffle = function(){ let x,y, to_x,to_y; let tmp; for (y=this.length-1;y>=0;y--) { for (x=this[y].length-1;x>=0;x--) { to_y=Math.floor(Math.random()*this.length); to_x=Math.floor(Math.random()*this[to_y].length); /* bbl */ tmp=this[y][x];this[y][x]=this[to_y][to_x];this[to_y][to_x]=tmp; } } }; Array.prototypeをこれに入れ替えてください。 ミニ解説 一応、横軸が「このサンプルでは10個」だったが、 可変長にしておきました。 基準値「y」の位置毎に可変長の「x」をサンプリングさせるようにしてあります。 bblはバブルになります。 変数は衝突へのこだわりも考えて、let式で記載。 object.lengthは元々固定値なので、ループで回してもOKなんですが、 初期値からの逆方向ループにて作成 (この技は一生使うと思うので覚えておいてよいかと) 1~10までループさせようが、10~1までループさせようが、 速度は同じであるって理屈です。 しかし、例えばx_max() のような「関数」で取得する必要がある場合、 大量にオーバーヘッドが減らせます。 という、2段配列シャッフルのコアを適当に作成してみましたが。 どうでしょうか?
お礼
完璧なBAでした!
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>全セルデータを >まんべんなくシャフルするのが >テーマです。 なので、2重配列なので、シャッフルも2重配列で 行うって意味で書いたので、その要件定義は満たすと思いますよ。
補足
>第2Arrayのソートなりシャッフルを入れれば、 解決します!。 具体的なコードをご教示ください。 よろしくお願いいたします。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
ちと、最初、ミスったので真面目に、 実際にデバッガーで追ってみました。 Array.prototype.shuffle = function(){ の時の、thisポインタは、 this: Array(5) 0: (10) ['83', '64', '18', '51', '36', '45', '84', '22', '16', '25'] 1: (10) ['春', '夏', '秋', '冬', '朝', '昼', '番', '花', '鳥', '風'] 2: (10) ['arm', 'bat', 'cat', 'dog', 'egg', 'fig', 'gal', 'hit', 'ink', 'joy'] 3: (10) ['1.8', '7.8', '1.4', '7.5', '6.2', '6.5', '5.1', '7.9', '7.2', '2.8'] 4: (10) ['月', '天', '地', '人', '愛', '4.3', '3.5', '8.4', '6.1', '6.4'] length: 5 こんな風に食っているようで、これが原因でしょう。 それをクローン'b'に対してソートを行っている。 なのでbは、length=5なので、縦軸でのソートだけを 行っていると判断されるが、 >行のシャッフルは出来るが、列のシャッフルがされていない 現象ともあっているので、これが原因ですね。 この場合、b=thisのクローンは、array array型になるので、 それを治せば、治ります!。 ってことで、第2Arrayのソートなりシャッフルを入れれば、 解決します!。 が回答になります。 ちょっと私も驚いたのが、 この場合のArrayへのプロトタイプ追加が、 [][] 形式になるとは、かなり驚きましたね。。 子インスタンス側ではなく、根本オブジェクト自体が、 すでに拡張されているメモリダンプ結果だったので、 お?!と、私もこれは^^楽しめましたよ!
お礼
ご回答ありがとうございます。
補足
//行のシャッフル関数 Array.prototype.shuffle = function(){ //略 }; ここに手を加えれば一挙に解決できる筈です。 なぜなら、 上記の関数は、行のみのシャッフルしか していないのだから。 ご提案の方法だと、 1行目は漢字1文字のみ ・・・ 5行目は英単語のみ そのようなシャフルで、偏っていませんかね。 全セルデータを まんべんなくシャフルするのが テーマです。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>cells[j].innerHTML = rowData[i][j]; 失礼しました。 これ根元がTR検索になってるので、原因違いますね。 違う所っぽいです。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
ざっと見ですが。 違和感がある部分が、 for (j=0; j<cells.length; j++) { cells[j].innerHTML = rowData[i][j]; } ここでしたね。 (慣れてくるとソース見ると気持ち悪く感じる部分を みつけやすくなりますのでね) cells[j].innerHTML = rowData[i][j]; jが単層ループしている事。 iの変化に対する増減値が書いていない事。 y*x_max+x; のように、横方向の最大値を、y方向に掛け算して、xを加算。 そうしないと「同じ場所を書き換え続ける」 のが、原因ではないかと。
お礼
ご回答ありがとうございます。
補足
要件の ・全セルデータをまんべんなくシャフル 確かにできておりました。 丁寧な解説付きでとても役立つ回答を 頂きまして、厚く御礼申し上げます。 m(_ _)m