0

我试图找到从commentCount和的属性likeCount都等于 0 的对象中删除属性的最有效方法。在下面的示例中,Activity.3将被删除。我不想用 a 循环它们,$.each()因为这似乎需要更多的时间。

Activity = {
    0 : {
    'commentCount' : 10,
    'likeCount' : 20    
    },
    1 : {
    'commentCount' : 0,
    'likeCount' : 20    
    },
    2 : {
    'commentCount' : 10,
    'likeCount' : 0    
    },
    3 : {
    'commentCount' : 0,
    'likeCount' : 0    
    }
}

更新

该对象的创建情况受到质疑。澄清一下,该Activity对象内部最多可以有 300 万个属性。它在服务器端生成为 AJAX JSON 响应,并保存到内存中。它不仅仅包括在其他地方使用的commentCountlikeCount所以我不能让服务器不响应那些和 0 都为 0 的commentCount东西likeCount

4

3 回答 3

4

啊,过早优化的味道^_^

你有多少这样的物品?您需要清洁多少?如果答案是“少于 100 万”和“一次或很少”,则可能不值得费心。

如果您需要一种快速且最佳的方法,这里有一个想法:为属性创建一个新的数据结构和设置器。每次设置它们时,检查它们是否都是0并将它们放入“杀死”列表中。

这样,您只需要遍历杀死列表。

[编辑]有几百万个对象并且需要快速清理,杀死列表是要走的路,特别是当条件很少时(只有几个对象匹配)。

只需编写一个更新这些属性的函数,并确保所有代码都通过它来更新它们。然后,您可以在那里管理杀戮列表。

或者,您可以在调用该函数后立即删除该对象,将两者或第二个属性都设置为 0。

于 2012-06-19T18:46:26.497 回答
0

这只是一个起点,但是这样的事情怎么样?基本上,它根据它们likeCount和的总和将活动放入桶中commentCount。它可以很容易地杀死所有没有喜欢或评论的活动,但我认为这是一个权衡。我不确定你是如何插入这些东西并阅读它们的。所以,你必须决定这是否值得。

var ActivityMgr = function(){
    if(!(this instanceof ActivityMgr)){
        return new ActivityMgr();
    }

    this.activities = {};
};

ActivityMgr.prototype.add = function(activity){
    var bucket = parseInt(activity.commentCount, 10) + parseInt(activity.likeCount, 10);

    if (this.activities[bucket] === undefined) {
        this.activities[bucket] = [activity];
    }
    else {
        this.activities[bucket].push(activity);
    }

    this.cleanse();
};

ActivityMgr.prototype.cleanse = function(){
    this.activities[0] = [];
};

//Usage:
var activityMgr = new ActivityMgr();
activityMgr.add({
    likeCount: 0,
    commentCount: 10
}); 

编辑: 发布后,很明显,如果您以这种方式添加项目,如果他们没有喜欢或评论,您就不能添加它们。我的猜测是事情并没有那么简单,所以请提供一些关于如何添加和更新内容的详细信息。

于 2012-06-19T19:13:01.143 回答
0

我要添加第二个答案,因为这个解决方案来自一个完全不同的角度。在这个解决方案中,我试图找到删除不需要的条目的最快方法。我不知道没有循环的任何方法,但我可以想到几种方法来使用 jQuery 以及原始 javascript 的循环来做到这一点。

这个 jsperf 并排显示了所有的测试用例。

我将解释每个测试以及与每个测试相关的注意事项。

  1. Raw JS:最慢的选项。看起来 jQuery 知道他们在用他们的$.eachand$.map循环做什么。

    var obj;
    for (var field in Activity) {
        if (Activity.hasOwnProperty(field)) {
            obj = Activity[field];
            if (obj.commentCount === 0 && obj.likeCount === 0) {
                delete Activity[field];
            }
        }
    }
    
  2. $.each: 并列第二名。比上面的原始 js 循环更简洁的语法和更快的速度。

    $.each(Activity, function(key, val){
        if (val.commentCount === 0 && val.likeCount === 0) {
            delete Activity[key];
        }
    });
    
  3. $.map(对象版本):并列第二名。警告:仅在 jQuery >= 1.6 中支持。

    Activity = $.map(Activity, function(val, key){
        if (val.commentCount === 0 && val.likeCount === 0) {
            return null;
        }
    });
    
  4. $.map(阵列版本):最快的选项。警告:您必须使用该$.makeArray函数将对象转换为数组。我不确定这是否适合您的需求。

    var arrActivity = $.makeArray(Activity);
    Activity = $.map(arrActivity, function(val, key){
        if (val.commentCount === 0 && val.likeCount === 0) {
            return null;
        }
    });
    

结论$.map如果您首先使用将对象转换为数组, 它看起来是最快的$.makeArray

于 2012-06-19T23:06:06.803 回答