我有以下小提琴:http://jsfiddle.net/mauricederegt/MhhBc/
它包含一个带有javascript生成的列表。每个<a>
都有一个随机选择的类。这种随机选择使用:
var randomClass;
randomClass = Math.round(Math.random() * 10 + 0);
这会产生一个随机的nr。这个我用来获得这里定义的随机类:
var classes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
因此,如果随机nr是2
,则该类将为b
这很完美。我遇到的问题是我希望每个类(或随机nr)至少使用两次,直到达到完整列表的末尾。 (小提琴有一个非常短的列表,真正的列表更长,也包含多个<ul>
)。
示例:因此,如果随机选择的nr为5
,则会给出类e
。这意味着必须再次使用此nr /类,但也必须随机放置在所有不同的列表上。如果随机nr恰好在列表的后面再次5
,则可以多次使用nr / class。
整个列表中使用的<a>
总量始终是均匀的。
另一个例子:
因此,超过6 <a>
的类可以是:a, d, a, e, e, d
。所有课程都在那里,并且都是随机的。
这是错误的:a, d, b, b, e, c
。这是当前的情况,并且类没有使用两次
希望我能够清楚地解释这个问题。我的英语不是最好的:)。
亲切的问候,
答案 0 :(得分:1)
修改 - 替换了以前的解决方案,因为它没有在所有ul
代码中重复
我已更新您的代码,现在它总是在所有<ul>
代码中至少两次添加每个类。
我需要预先确定项目总数。目前我已将count作为常量totalCount
添加,因为我不想两次遍历JSON对象只是为了获得总计数而我想让主代码首先工作。
也许总计数可以作为JSON对象的一部分向下发送,作为对象根目录中的单独属性?
无论哪种方式,项目的总数必须以某种方式预先知道。
我将一些必需的变量移动到更全局的范围,因为每个ul
都会调用render方法。
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;
};
(使用浏览器中的调试工具检查呈现的HTML中的结果)
你注意到现在内部循环中发生的第一件事,我正在检查是否有剩余的可用类,如果没有,我将可用类重新设置为原始列表。
只有当您的原始可用类列表少于总项数时,才会发生这种情况。
我仍然会在每个列表项的迭代过程中从可用类列表中删除选定的类,以确保每个类至少会出现两次。
我仍然在另一个数组中记录选定的类,然后在项目列表的中途使用它来重新设置可用类的数组。
如果项目总数是奇数或偶数,则代码有效。
对于偶数项目,我们只需通过除以2来测量laf-way标记
对于奇数个项目,我确保标记为中途(totalCount -1) / 2
,然后将随机类添加到已选择的类作为附加可用类。
现在这应该按预期工作.....
编辑(03-Sep-2021)
我检查了代码,其中有一个逻辑错误。 itemCount
在中途标记后重新设定。
此代码:
var itemCount = selectedClasses.length;
假设曾经: //将声明移入外部范围并立即增加计数。 itemCount + = 1
现在,代码正在按照我的计划执行所有操作。
所有链接都获取类,所有类至少使用两次,看到我们只有11。 没有链接永远不会没有一个类,因为总有一个来源可供选择。
关于确保每个课程至少使用一个课程的问题。这取决于可用类别与总项目的中途标记的比率。
如果您使用11个类作为可能的来源,并且至少有22个预期链接,那么您使用的所有类和将被使用两次。
如果您使用20个课程和22个项目,那么否并非所有课程都会被使用。原因是您的原始要求to use each selected class at least twice
。
为了确保所有选定的类至少使用两次,我将记录在名为selectedClasses
的单独数组中进行的每个选择。我们已经处理了一半可能的项目,我用所选的类数组替换了源类。现在,另一半项目只能从已选择的类列表中进行选择,从而确保每个类至少使用两次。
考虑一下,如果你有20个类的数组和总共22个项目你不能使用所有类至少一个如果你在同一时间想要确保每个被选中的类被使用至少两次。这些要求相互矛盾。
可用类的数量必须小于或等于项目总数的一半,以确保至少使用所有类和所有选定的类至少使用两次。
我希望这是有道理的,但如果你被卡住了,可以随意在评论部分开始聊天,我可以再次与你一起检查代码,没问题。