【发布时间】:2011-06-25 21:03:13
【问题描述】:
情况
我目前正在编写一个在 html 元素中显示随机引用的 javascript 小部件。引号存储在 javascript 数组中,以及它们在 html 元素中显示的次数。要显示的报价不能与之前显示的报价相同。此外,选择报价的机会取决于它在 html 元素中的先前出现次数。 (与选择显示的其他引号相比,出现次数越少,机会越大。
当前解决方案
我目前已经通过使用大量循环遍历各种数组来使其工作(由于我严重缺乏 javascript 知识)。虽然这目前有效(!!)我发现这个解决方案对于我想要实现的目标来说相当昂贵。
我在寻找什么
- 从数组中删除数组元素的替代方法,当前循环遍历整个数组以找到我要删除的元素并将所有其他元素复制到新数组中
- 根据出现次数从数组中计算和选择元素的替代方法
- 您注意到我应该/可以做的任何其他事情,同时仍然在情况下执行规定的业务规则
守则
var quoteElement = $("div#Quotes > q"),
quotes = [[" AAAAAAAAAAAA ", 1],
[" BBBBBBBBBBBB ", 1],
[" CCCCCCCCCCCC ", 1],
[" DDDDDDDDDDDD ", 1]],
fadeTimer = 600,
displayNewQuote = function () {
var currentQuote = quoteElement.text();
var eligibleQuotes = new Array();
var exclusionFound = false;
for (var i = 0; i < quotes.length; i++) {
var iteratedQuote = quotes[i];
if (exclusionFound === false) {
if (currentQuote == iteratedQuote[0].toString())
exclusionFound = true;
else
eligibleQuotes.push(iteratedQuote);
} else
eligibleQuotes.push(iteratedQuote);
}
eligibleQuotes.sort( function (current, next) {
return current[1] - next[1];
} );
var calculatePoint = eligibleQuotes[0][1];
var occurenceRelation = new Array();
var relationSum = 0;
for (var i = 0; i < eligibleQuotes.length; i++) {
if (i == 0)
occurenceRelation[i] = 1 / ((calculatePoint / calculatePoint) + (calculatePoint / eligibleQuotes[i+1][1]));
else
occurenceRelation[i] = occurenceRelation[0] * (calculatePoint / eligibleQuotes[i][1]);
relationSum = relationSum + (occurenceRelation[i] * 100);
}
var generatedNumber = Math.floor(relationSum * Math.random());
var newQuote;
for (var i = 0; i < occurenceRelation.length; i++) {
if (occurenceRelation[i] <= generatedNumber) {
newQuote = eligibleQuotes[i][0].toString();
i = occurenceRelation.length;
}
}
for (var i = 0; i < quotes.length; i++) {
var iteratedQuote = quotes[i][0].toString();
if (iteratedQuote == newQuote) {
quotes[i][1]++;
i = quotes.length;
}
}
quoteElement.stop(true, true)
.fadeOut(fadeTimer);
setTimeout( function () {
quoteElement.html(newQuote)
.fadeIn(fadeTimer);
}, fadeTimer);
}
if (quotes.length > 1)
setInterval(displayNewQuote, 10000);
考虑的替代方案
-
总是选择出现次数最少的数组元素。
决定不这样做,因为这会/可能会在动画中显示过于明显的模式
-
组合多个for循环以减少工作量
决定不这样做,因为这会使代码变得深奥,下周我可能再也看不懂代码了
jsFiddle 参考
更新
用提到的技术重写了我的函数,虽然我担心这些技术仍然循环遍历整个数组以找到它的要求,至少我的代码看起来更干净:)
在这里阅读答案后使用的参考资料:
【问题讨论】:
-
接受的答案非常好。另外,我建议"without" function, from underscore.js。实际上,underscore.js 会帮助你解决一些数组问题。
标签: javascript jquery arrays sorting loops