1

多次元配列を動的に構築しようとしています。

動的に構築したい理由は、配列が 5 桁のチャンクで 1 ~ 1000 のように大きくなった場合です。
次のように書くと非常に時間がかかります。

[1, 2, 3, 4, 5],,,,,[996, 997, 998, 999, 1000]

今日は一日中苦労していたので、今は完全に立ち往生しているので、この質問を投稿することにしました。

これは、動的に構築したい配列です (解決済みの私の以前の投稿):
多次元配列シャッフル ランダム

動的配列が適切に構築されたら、fisherYates() 関数を 'outerArr.forEach(fisherYates); で呼び出したいと思います。 ' 次のような結果を得るには:

[4,2,3,5,1],[7,10,6,9,8],[11,15,12,14,13],[18,17,16,20,19],[22,21,25,23,24]


配列は、画像のフェードアウト/フェードインに使用されます。
1. フェードイン 5 つのランダム画像の最初のセット 1-5
2. フェードアウトの最初のセット
3. 5 つのランダム画像の 2 番目のセット 6-10
4. フェードアウトの 2 番目のセット
5. 5 つのランダム画像の 3 番目のセット 11-15
6.などの上....

次のような配列値を使用します。

$currImg = $('.rotator-image:visible', $currLi);
$next = $('.img' + outerArr[a][b], $currLi);
$currImg.fadeOut(1000);
$next.fadeIn(1000);

私はこれらのリンクの助けを借りてこれを解決しようとしました:
jQuery.map
Create multidimentional array with dynamic form
Pointy's code in this post .

いくつかのメモ: 私は"var outerArr = new Array();". 避けるべきだとどこかで読んだ(?)。可能であれば、.push と $.makeArray (および $.map) を使用して、これを jQuery の方法で実現したいと考えています。ただし、任意のアプローチが高く評価されます。

これが私が持っているコードです(私のコメントを見るためにJSfiddleのJavascriptウィンドウを増やしてください):(そしてここにも)

function fisherYates(myArray) {
    var i = myArray.length, j, tempi, tempj;
    if (i === 0) return false;
    while (--i) {
        j = Math.floor(Math.random() * (i + 1));
        tempi = myArray[i];
        tempj = myArray[j];
        myArray[i] = tempj;
        myArray[j] = tempi;
    }
}

var outerArr = [];
var innerArr = [];
var fakeArr = 0;
var zz = 0;

for (var z = 1; z < 26; ++z) {
    ++zz;
    if (zz != 5) {
        fakeArr = fakeArr + z + ",";
    } else {
       fakeArr = fakeArr + z;
       var realArr = $.makeArray(fakeArr);
       innerArr.push(realArr);
       outerArr.push(innerArr);
       innerArr = [];
       innerArr.length = 0;
       fakeArr = "";
       fakeArr.length = 0;
       zz = 0;
    }
}
// Shuffle/Randomize the numbers in each chunk but not the order of the five chunks
outerArr.forEach(fisherYates);
alert(outerArr);

問題は、配列から値を取得したいときです。単一の値が得られません (outerArr[1][3] のように 9 が表示されるはずです)。私はそれぞれの完全なチャンク (6,7,8,9,10 など) のみを取得します。$.map を使用する必要があると思いますが、私の例で $.map を使用する方法がわかりません。シャッフル/ランダム関数 (つまりouterArr.forEach(fisherYates);) は、コードが現在のように機能しません。

配列もランダム化する必要があります(上部の最初のリンクで説明されているように)が、動的部分が機能すると、シャッフル/ランダムが機能するはずです。

4

2 に答える 2

1

jQueryでこれを行うべきだという考えで、あなたは本当に間違った方向に進んでいます。この種のコードは、jQuery が得意とするものとはまったく異なります。jQuery はDOM 操作ライブラリであり、この種のコーディング用の汎用 JavaScript ライブラリではありません。

これらの種類の配列操作に役立つライブラリが必要な場合は、underscore.jsまたは同様の新しいLo-Dashから始めるとよいでしょう。これらのライブラリには、あらゆる種類の配列およびオブジェクト操作関数があります。これらの両方のライブラリのドキュメントを確認し、役立つかどうかを確認してください。(ドキュメントを読んだ後、どちらを選択すればよいかわからない場合は、どちらを選択しても問題ありませんが、私の提案は Lo-Dash です。)

それ以外の場合は、昔ながらのループなどを使用して、生の JavaScript コードを単純に記述する必要があります。

いくつかのメモ: 私はvar outerArr = new Array();. 避けるべきだとどこかで読んだ(?)。

代わりに使用しているのはvar outerArr = [];. それは問題ありません。実際、最近ではこれが推奨される方法です。しかし、それは見た目の違いにすぎません。new Array()[]まったく同じことを意味し、まったく同じように機能します。一方を他方に変更しても、問題が発生したり、問題が修正されたりすることはありません。

また、コードのインデントがめちゃくちゃでした。どのステートメントが何の中にネストされているかを判別することは不可能でした。だから私はインデントをきれいにする自由を取った。それをチェックして、私がそれを正しく理解していることを確認してください。

コードに関数があるfisherYates()ようですが、この関数は呼び出されません。これが何についてなのかわかりませんが、おそらく明確にすることができます。

偽の配列は何のためですか? なぜ偽の配列と実際の配列が必要なのですか?

このコードには、何もしない 2 つのステートメントがあります。

   innerArr = [];
   innerArr.length = 0;  // does nothing
   fakeArr = "";
   fakeArr.length = 0;  // does nothing

と の値はそれぞれとであるため、innerArrとの両方fakeArrの長さはすでにゼロであるため、再度ゼロに設定する必要はありません。[]""length

最後に 1 つの提案: JavaScript コードをすぐに書き出そうとするのではなく、入力と出力が何であり、どのような手順でそこに到達できると思われるかを正確に英語で (念入りに詳細に) 書き出す必要があります。投稿した説明は途中までですが、多くの詳細が欠落しています。これらの詳細をすべて英語または疑似コードで書き出すことができれば、実際のコードを書きやすくなる可能性があります。

これがあなたの質問に答えていないことはわかっていますが、考える材料にはなるはずです! :-)

于 2013-05-19T04:43:34.287 に答える
0

以前に私の質問に答えてくれたユーザー Michael Geary と nnnnnn の助けを借りて、周りを検索した後、解決策を得ました。この投稿で役立つコードを見つけました。

私が探していたコードは次のようになります。コメント付きでJSFiddleにも投稿されまし た。長いコメントを表示するには、JSFiddle JavaScript ウィンドウを展開してください。

function fisherYates(myArray) {
    var i = myArray.length, j, tempi, tempj;
    if (i === 0) return false;
    while (--i) {
        j = Math.floor(Math.random() * (i + 1));
        tempi = myArray[i];
        tempj = myArray[j];
        myArray[i] = tempj;
        myArray[j] = tempi;
    }
}

var outerArr = [];
var innerArr = [];
var f = 0;

for (var z = 1; z < 27; ++z) {
    ++f;
    if (f <= 5) {
        innerArr.push(z);
    } else {
        outerArr.push(innerArr);
        innerArr = [];
        f = 0;
        --z;
    }
}

alert(outerArr);
outerArr.forEach(fisherYates);
alert(outerArr);
alert(outerArr[0][0]);
alert(outerArr[4][4]);

私は評判15を持っていないので、Michael Gearyの回答を+1することはできません

于 2013-05-24T15:35:27.823 に答える