如何在JavaScript对象之间查找通用属性 [英] How to find common properties between JavaScript objects

查看:68
本文介绍了如何在JavaScript对象之间查找通用属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

找到对象数组的公共/不同属性的最佳/最有效方法是什么?

What is the best/most efficient way to find the common/different properties of an array of objects.

我需要确定所有对象中都存在的属性集,并且所有属性都具有相同的值(公用). 最好我也想获得一个具有所有其他属性(diff)的数组.

I need to identify the set of properties that exists in all objects and all have the same value(the common). Preferably I would also like to get an array with all other properties (the diff).

我一直在寻找可以做到的高效库/函数.但是什么也没找到.所以我自己尝试了.

I have searched for an efficient library/function that can do it. But didn't find anything. So I tried on my own.

考虑以下JS对象数组:

Consider this array of JS objects:

var objects = [{
    id: '2j2w4f',
    color: 'red',
    height: 20,
    width: 40,
    owner: 'bob'
}, {
    id: '2j2w3f',
    color: 'red',
    height: 20,
    width: 41,
    owner: 'bob'
}, {
    id: '2j2w2f',
    color: 'red',
    height: 21,
}, {
    id: '2j2w1f',
    color: 'red',
    height: 21,
    width: 44
}];

我想将color(值为red)标识为唯一的公共属性. 请注意,它们没有相同的属性集.例如. owner不是常见属性.

I would like to identify color (with value red) as the only common property. Note that they do not have the same set of properties. E.g. owner is not a common property.

这是我自己尝试解决的问题(使用lodash):

This is my own attempt to solve it (using lodash):

function commonDifferentProperties(objects) {
    // initialize common as first object, and then remove non-common properties.
    var common = objects[0];
    var different = [];
    var i, obj;

    // iterate through the rest (note: i === 0 is not supposed to be covered by this)
    for (i = objects.length - 1; i > 0; i--) {
        obj = objects[i];
        // compare each property of obj with current common
        _.forOwn(obj, function (value, key) {
            // if property not in current common it must be different
            if (_.isUndefined(common[key])) {
                if (!_.contains(different, key)) {
                    different.push(key);
                }
            } else if (common[key] !== value) { // remove property from common if value is not the same
                delete common[key];
                different.push(key);
            }
        });

        // check that all properties of common is present in obj, if not, remove from common.
        _.forOwn(common, function (value, key) {
            if (_.isUndefined(obj[key])) {
                delete common[key];
                different.push(key);
            }
        });

    }

    return {
        common: common,
        different: different
    };
}

jsFiddle与示例

我也尝试过mapReduce方法,但这似乎更糟.

I have also tried a mapReduce approach, but that seemed even worse.

我仍然认为这似乎有些复杂/耗时,我将在1000-10000个对象或更多对象(每个对象具有20-50个属性)上执行此操作.

I still think this seems a bit complex/time consuming, and I will do this on 1000-10000 objects or more with 20-50 properties each.

有什么建议吗?

推荐答案

在您的解决方案中,有两件事看起来是错误的:

There are two things that are look wrong in your solution:

  • 通过var common = objects[0];,您不会复制对象,因此您将破坏objects
  • 您都检查obj中是否存在common的所有属性,而且将obj的每个属性与当前common进行比较.似乎太过分了.起初没有意识到您也需要different属性.
  • By var common = objects[0]; you don't copy the object, so you're going to corrupt the objects
  • You both check that all properties of common is present in obj, but also compare each property of obj with current common. That seems to be once too much. Didn't realize at first that you needed the different properties as well.

我要分两遍遍遍数据.在第一个中,您将所有明显的属性收集在一个对象中,在第二个中,您测试它们是否常见:

I'd loop over the data in two passes. In the first, you collect all apparent properties in one object, in the second you test whether they're common or not:

function commonDifferentProperties(objects) {
    var common = _.reduce(objects, function(acc, obj) {
        for (var p in obj)
            acc[p] = obj[p];
        return acc;
    }, {});
    var different = _.reduce(objects, function(acc, obj) {
        for (var p in common)
            if (common[p] !== obj[p]) {
                delete common[p];
                acc.push(p);
            }
        return acc;
    }, []);
    return {
        common: common,
        different: different
    };
}

这篇关于如何在JavaScript对象之间查找通用属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆