javascript - 嵌套循环花费的时间太长,几乎使浏览器崩溃

标签 javascript json angularjs

我的应用程序正在检索 json 数据。 json 文件有近千个单词,结构如下:

{"THEMES":{"THEME1":["ITEM1","ITEM2","ITEM3"],"THEME2":["ITEM1",...]...}}

该文件大约25kb。在我的应用程序的某个时刻,我需要比较哪个项目与哪个主题相关,以在 Angular ng-repeat 与单词相关的选定项目内生成。这是我的 Angular 处理这些的部分:

<div class="well">
    <div class="input-group" bindonce ng-repeat="word_in_list in words_list">
        <div class="form-group">
            <select>
                <option ng-selected="word_in_list.select == theme" ng-repeat="theme in themes" value="{{theme}}">{{theme}}</option>
            </select>
        </div>
        <div class="form-group">
            <input type="text" class="form-control" placeholder="{{word_in_list.input}}">
              <span class="input-group-addon">
                <input type="checkbox" ng-click="listControlWord($event, word_in_list.input, word_in_list.select)">
              </span>
        </div>
    </div>
</div>

重要的部分是以下部分:

$http.get('json/word_bank.json')
    .success(function (result) {
        $scope.themes = Object.keys(result.TEMAS);
        for (var i = 0, z = $scope.themes.length; i < z; i++) {
            for (var j = 0; j < result.TEMAS[$scope.themes[i]].length; j++) {
                $scope.words_list.push({select: $scope.themes[i], input: result.TEMAS[$scope.themes[i]][j]});
            }
        }
    });

问题是浏览器需要大约两分钟的时间来呈现信息,并且经常使浏览器崩溃。循环工作正常,信息检索正常,只是所花费的时间是 Not Acceptable 。如何优化这些循环?

最佳答案

你的算法是 O(N^2),除了特定于领域的启发式算法之外,确实没有办法解决这个问题。话虽如此,您可以按照您的暗示以不同的方式看待这一点。如果我正确理解问题的话,你真的在​​尝试连接数组。

这是一个performance test为了你想要实现的目标。

不幸的是,我认为您无法使用最有效的方法(利用 apply),但您可以使用这些技术的某种组合。通过连接所有数组,并保留一些有关连接数组中的哪些索引与哪些“键”相关的元数据,您可以将其减少到 O(N)。

类似...

<!doctype html>
<html lang="en">
    <head>
        <title>Test</title>
        <script src="d3.js" charset="utf-8"></script>
    </head>

    <body>
        <div id="divPerfTest"></div>

        <script>
            var result = {"THEMES":{"THEME1": ["ITEM1","ITEM2","ITEM3"],"THEME2":["ITEM1","ITEM2"]}};
            var keys = Object.keys(result.THEMES),
                master = [],
                masterBreaks = [],
                themeNames = [],
                word_list = [],
                theme, idx, key,
                breakIdx = 0,
                breakOffset = 0,
                outStr = "";


            for(idx = 0; idx < keys.length; idx++) {
                key = keys[idx];
                theme = result.THEMES[key];
                master = master.concat(theme);
                masterBreaks.push(theme.length);
                themeNames.push(key);
            }

            masterBreaks.push(master.length); // need the last break to exceed last index

            for (idx = 0; idx < master.length; idx++) {
                if (idx >= masterBreaks[breakIdx] + breakOffset) {
                    breakOffset += masterBreaks[breakIdx++];
                }

                word_list.push({
                    select: themeNames[breakIdx],
                    input: master[idx]
                });
            }

            for(idx=0; idx<word_list.length; idx++) {
                outStr += "[ " + idx.toString() + " ] Select: " + word_list[idx].select + ", Input: " + word_list[idx].input + "<br/>";
            }

            document.querySelector("#divPerfTest").innerHTML = outStr;
        </script>
</body>
</html>

但是,我认为更好的方法是更改​​数据架构。是否可以重构或修改数据,使得主题的名称是对象的属性,而项目列表是同一对象的另一个属性,而不是使用定义不同主题的变量名称。然后你维护这些对象的列表......

{ THEMES: [
    { id: "THEME1",
      data: ["ITEM1", "ITEM2"] },
    { id: "THEME2",
      data: ["ITEM1", "ITEM2", "ITEM3"] }
}

关于javascript - 嵌套循环花费的时间太长,几乎使浏览器崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32187433/

相关文章:

javascript - 基于 Javascript if else 语句更改样式表

javascript - AngularJs。通过 ajax 加载的数据未显示在 View 中

JavaScript:BufferLoader...loader.onload 不是函数

javascript - 谷歌图表工具提示不工作

python - 如何将多个 python 对象转储到 json 文件以及从 json 文件加载多个 python 对象?

javascript - 无法从 json 填充 html 表

angularjs - Angular js中的内容可编辑

angularjs - 无法让 `ion-nav-view` 工作

javascript - 如何制作一个搜索功能,搜索产品描述的表格或数组并显示相应的代码

javascript - $.GetJson() 无法从本地文件夹加载 JSON 文件