javascript - javascript 中过度 for() 循环的替代方案

标签 javascript jquery arrays sorting loops

情况

我目前正在编写一个 javascript 小部件,它可以将随机引号显示到 html 元素中。引号存储在 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 引用

http://jsfiddle.net/P5rk3/

更新

用提到的技术重写了我的函数,虽然我担心这些技术仍然会遍历整个数组以找到它的要求,但至少我的代码看起来更干净:)

阅读此处答案后使用的引用资料:

最佳答案

我建议最受支持的数组函数(如果不支持则很容易添加):

[].splice(index, howManyToDelete); // you can alternatively add extra parameters to slot into the place of deletion
[].indexOf(elementToSearchFor);
[].filter(function(){});

其他有用的函数包括 forEachmap

我同意将所有工作合并到一个巨大的循环中是丑陋的(而且并非总是可行),而且这样做你获益甚微,因此可读性绝对是赢家。尽管这些数组函数不需要太多循环。

关于javascript - javascript 中过度 for() 循环的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6480514/

相关文章:

javascript - 使用javascript访问数据库?

javascript - jQuery:如何用文本区域 $ ('#myId' ).attr ('value' ) 中的另一个文本替换某些文本?

jquery - 防止 child 点击事件,产生由 parent 触发的弹出窗口

Java 按顺序迭代并打印多个数组

javascript - Nodejs中的数组内存分配

javascript - 检查多个数组值是否相等

javascript - 出现垂直间隙 - jQuery Masonry -(无缝照片网格)

c++ - 动态填充结构数组

javascript - 在渲染器进程中使用 Electron 进度条

javascript - 点击链接时的点击计数器 PHP/JS