从没有循环的对象中删除某些属性

时间:2012-06-19 18:42:21

标签: javascript jquery object

我正在尝试找到从commentCountlikeCount的属性都等于0的对象中删除属性的最有效方法。在以下示例中,Activity.3将被删除。我不希望用$.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,因此我不能让服务器不对commentCount和{{1}的0都做出回应}}

3 个答案:

答案 0 :(得分:4)

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

你有多少这些物品?你有多少需要清理它们?如果答案是“少于100万”和“一次或很少”,那么可能不值得打扰。

如果您需要快速且最佳的方式,请注意以下事项:为属性创建新的数据结构和设置器。每次设置它们时,检查它们是否都是0并将它们放入“kill”列表中。

这样,你只需要遍历杀戮名单。

[编辑] 有数百万个对象需要快速清理,杀戮清单是可行的方法,特别是当条件很少时(只有少数几个对象匹配)。

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

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

答案 1 :(得分:0)

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

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
}); 

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

答案 2 :(得分:0)

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

This jsperf并排显示所有测试用例。

我将解释每个测试以及与每个测试相关的警告。

  1. Raw JS:最慢​​的选项。看起来jQuery知道他们正在使用$.each$.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;
        }
    });
    
  5. <强>结论 如果您首先使用$.map将对象转换为数组,则$.makeArray看起来最快。