編集-すべての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回使用されるようにするには、使用可能なクラスの数をアイテムの総数の半分以下にする必要があります。
これが理にかなっていることを願っていますが、行き詰まっている場合は、コメントセクション内でチャットを開始してください。コードをもう一度確認できます。問題ありません。