0

在我使用 underscore.js 和 jquery 构建的一个简单的 Web 应用程序中。对于所有人(js 对象)的列表,我正在过滤掉他们访问过的所有地方(js 对象)的列表。人员列表是一个td带有地点图像图标的 html 表格,单击该图标会显示他们访问过的所有地点的列表。图标只需要对至少访问过一个地方的人显示。这里的问题是人员和地点的计数出现了2000100。所以下面的代码执行2000*100组合。浏览器抱怨我没有响应的脚本。代码如下

_.each(peopleList, function (person, index, list) {

    //filter the respective places for people
    var visitedPlaces = _.filter(places, function (place) {
        return place.PeopleId == person.Id;
    });

    if (_.isEmpty(visitedPlaces)) {
        $("a#" + place.PeopleId).remove();
    }
});

死的简单是不是。对于每个人,检查访问过的地方是否对他进行了跟踪。我如何优化上述代码以解除阻塞和响应。尝试在某些地方放置_.defer_.delay但没有改善

4

3 回答 3

2

FWIW,这是我用下划线解决它的方法。

function removeNonTravelers(people, visits) {
    var travelers    = _.pluck(visits, 'PeopleId'),
        nonTravelers = _.reject(people, function (person) {
            return _.contains(travelers, person.Id);
        });

    $(_.map(nonTravelers, document.getElementById)).remove();
}

http://jsfiddle.net/FWzeN/

于 2013-04-24T11:29:29.810 回答
1

我的建议是去掉下划线并为此使用纯 JS:

function removeNonTravelers(people, visits) {
    var i, peopleId,
        numPeople = people.length,
        numVisits = visits.length,
        index = {}, nonTravelers = [];

    // index
    for (i = 0; i < numVisits; i++) {
        peopleId = visits[i].PeopleId;

        if (!index.hasOwnProperty(peopleId)) {
            index[peopleId] = 1;
        } else {
            index[peopleId]++;
        }
    }

    // find HTML elements to remove
    for (i = 0; i < numPeople; i++) {
        peopleId = people[i].Id;

        if (!index.hasOwnProperty(peopleId)) {
            nonTravelers.push(document.getElementById(peopleId));
        }
    }

    // remove them all at once
    $(nonTravelers).remove();
}

这是相当快的。如果我没有犯任何错误,您的测试用例(2000 人,100 个地点)在我相当过时的笔记本电脑(不包括 DOM 操作)上每秒执行超过 700 次操作。

自己试试:http: //jsperf.com/where-not-exists-in-javascript

于 2013-04-24T06:35:13.363 回答
0
var hashMap = {};

_.each(places, function(place) {
  hashMap[place.PeopleId] = place;
});

_.each(peopleList, function (person, index, list) {

    //filter the respective project documents
    var visitedPlaces = hashMap[person.id];

    if (visitedPlaces) {
        $("a#" + place.PeopleId).remove();
    }
});
于 2013-04-24T06:32:06.177 回答