1

私は次のフィドルを持っています:http://jsfiddle.net/mauricederegt/MhhBc/

これには、JavaScriptで生成されたリストが含まれています。それぞれ<a>にランダムに選択されたクラスが与えられます。このランダムな選択は、以下を使用して行われます。

var randomClass;
randomClass = Math.round(Math.random() * 10 + 0);

これにより、ランダムなnrが生成されます。このnrは、ここで定義されたランダムクラスを取得するために使用します。

var classes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];

したがって、ランダムなnrがである2場合、クラスは次のようになります。b

これは完全に機能します。私が抱えている問題は、完全なリストの最後に到達する前に、各クラス(またはランダムなnr)を少なくとも2回使用することです。(フィドルには非常に短いリストがあり、実際のリストには複数のリストも含まれています<ul>)。

例:したがって、ランダムに選択されたnrが5である場合、クラスが与えられeます。つまり、このnr / classを再度使用する必要がありますが、すべての異なるリストにランダムに配置する必要もあります。ランダムなnrがリストの後半にある場合は、nr/classを複数回使用できます5

リスト全体で使用される合計量<a>は常に均等です。

別の例:したがって、6を超えるクラス<a>は次のようになりますa, d, a, e, e, d。すべてのクラスが2回あり、すべてランダムです。

これは間違っています:a, d, b, b, e, c。これは現在の状況であり、クラスは2回使用されていません

問題を十分に明確に説明したことを願っています。私の英語は最高ではありません:)

敬具、

4

1 に答える 1

1

編集-すべてのulタグで繰り返されていなかったため、以前のソリューションを置き換えました

コードを更新しましたが、すべての<ul>タグに少なくとも2回は常に各クラスが追加されています。

事前にアイテムの総数が必要です。totalCount現在、合計カウントを取得するためだけにJSONオブジェクトを2回反復する必要がなく、メインコードを最初に機能させたいため、そのカウントを定数として追加しました。

たぶん、合計数は、JSONオブジェクトの一部として、オブジェクトのルートにある個別のプロパティとして送信できますか?

いずれにせよ、アイテムの総数は何とかして事前に知る必要があります。

必要な変数のいくつかをよりグローバルなスコープに移動しました。これは、renderメソッドがそれぞれに対して呼び出されるためulです。

var classes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
//var classes = ['a', 'd', 'f'];
var sourceClasses = [];
var totalCount = 6;
var selectedClasses = [];

Menu.prototype.render = function() {    
    // Get total item count between all arrays
    //debugger;    
    var ul = $("<ul />");

    $.each(this.data, function(i, e) {
        var li = $("<li />");

        //console.log(listItemCount);
        //debugger;
        $.each(e, function(j, f) {
            //debugger;
            // If we have no more classes left we re-set the list of items to the original source
            // SourceClasses.length will off course not be 0 ever if we already passed the half-way mark.
            if(sourceClasses.length === 0){
                for(index = 0; index < classes.length; index++){
                    sourceClasses.push(classes[index]);
                }
            }            

            var randomClass;
            randomClass = Math.round(Math.random() * (sourceClasses.length - 1) + 0);

            var selectedClass = sourceClasses[randomClass];

            li.append($("<a></a>", {
                href: f.url,
                text: f.title,
                class: selectedClass
            }));

            sourceClasses.splice(sourceClasses.indexOf(selectedClass), 1);
            selectedClasses.push(selectedClass);

            // Check for half-way mark.
            var itemCount = selectedClasses.length;

            if (totalCount % 2 != 0) {
                if (itemCount === (totalCount - 1) / 2) {
                    sourceClasses = selectedClasses;
                    var additionalClass = Math.round(Math.random() * (sourceClasses.length - 1) + 0);
                    sourceClasses.push(sourceClasses[additionalClass]);
                    selectedClasses = [];
                };
            } else {
                if (itemCount === totalCount / 2) {
                    sourceClasses = selectedClasses;
                    selectedClasses = [];
                };
            }
        });
        ul.append(li);
    });

    //console.log($($(ul).find("a")));
    return ul;
};

デモ-各クラスは、すべてのリストアイテムで少なくとも2回使用されます

(ブラウザのデバッガツールを使用して、レンダリングされたHTMLで結果を確認してください)

内側のループ内で最初に発生していることに気づきました。使用可能なクラスが残っているかどうかを確認し、残っていない場合は、使用可能なクラスを元のリストにリセットします。

これは、使用可能なクラスの元のリストがアイテムの総数より少ない場合にのみ発生します。

各リストアイテムの反復中に、使用可能なクラスのリストから選択したクラスを削除して、各クラスが少なくとも2回表示されるようにします。

選択したクラスを別の配列に記録しているので、アイテムのリストの途中で使用可能なクラスの配列を再設定するために使用します。

アイテムの総数が奇数または偶数の場合、コードは機能します。

合計アイテムの数が偶数の場合は、2で割ってラフウェイマーカーを測定します。
合計アイテムの数が奇数の場合は、必ず途中でマークを付け(totalCount -1) / 2てから、選択済みのクラスに追加の利用可能なクラスとしてランダムなクラスを追加します。 。

これはすべて期待どおりに機能するはずです.....

編集(203-Sep-2021)
コードを確認しましたが、論理的なバグがありました。itemCount中途半端なところでリセットされました。

このコード:

var itemCount = selectedClasses.length;

次のようになっていると仮定します。//宣言を外部スコープに移動し、カウントを着実に増やします。itemCount + = 1

これで、コードは計画どおりにすべてを実行します。

デモ-11のクラスプールで70のリンクを使用

すべてのリンクはgetクラスを取得し、すべてのクラスは少なくとも2回使用されます。これは、11しかなかったことを示しています。選択できるソースが常にあるため、リンクにクラスがなくなることはありません。

すべてのクラスが少なくとも1つ使用されていることを確認するための質問について。これは、アイテム全体の中間点に対する利用可能なクラスの比率によって異なります。

可能なソースとして11のクラスを使用し、少なくとも22の予想されるリンクを使用している場合、すべてのクラスが使用され 2回使用されます。

20のクラスと22のアイテムを使用している場合、すべてのクラスが使用されるわけではありません。その理由は、元の要件によるものですto use each selected class at least twice

選択したすべてのクラスが少なくとも2回使用されるようにするために、。という名前の個別の配列で行われた各選択を記録していselectedClassesます。可能なアイテムの半分を処理したものは、ソースクラスを選択したクラス配列に置き換えます。現在、アイテムの残りの半分は、すでに選択されているクラスのリストからのみ選択できるため、各クラスが少なくとも2回使用されるようになっています。

考えてみてください。20のクラスの配列と合計22のアイテムがある場合、同時に選択された各クラスが少なくとも2回使用されるようにしたい場合は、すべてのクラスを少なくとも1つ使用することはできません。これらの要件は互いに矛盾しています。

すべてのクラスが少なくとも1つ使用され、選択されたすべてのクラスが少なくとも2回使用されるようにするは、使用可能なクラスの数をアイテムの総数の半分以下にする必要があります。

これが理にかなっていることを願っていますが、行き詰まっている場合は、コメントセクション内でチャットを開始してください。コードをもう一度確認できます。問題ありません。

于 2012-09-02T22:34:36.570 に答える