【发布时间】:2014-04-21 14:23:14
【问题描述】:
找到对象数组的共同/不同属性的最佳/最有效方法是什么。
我需要识别存在于所有对象中并且都具有相同值(共同点)的属性集。 最好我还想获得一个具有所有其他属性(差异)的数组。
我已经搜索了可以做到这一点的高效库/函数。但是什么也没找到。所以我自己尝试了。
考虑这个 JS 对象数组:
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 不是公共属性。
这是我自己尝试解决的问题(使用 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
};
}
我也尝试了 mapReduce 方法,但似乎更糟。
我仍然认为这似乎有点复杂/耗时,我将对 1000-10000 个或更多对象执行此操作,每个对象具有 20-50 个属性。
有什么建议吗?
【问题讨论】:
-
你真的需要不同的属性吗?顺便说一句:修复了你的fiddle
-
不熟悉 lodash,但在我看来,您正在迭代每个对象的属性并将它们与第一个对象进行比较,这似乎是倒退的。您应该迭代 only 第一个对象的属性并将它们与其他对象进行比较(假设您只需要公共属性)。
-
您还通过调用
delete common[key];破坏了您的objects[0]。 -
我不会从第一个对象中删除,而是从一个空对象开始并添加公共属性。它还将避免@LeonidBeschastny 提到的问题
-
@MattBurland 是的,我需要不同的一次。但是,一旦我需要知道给定的属性是否不常见,我也可以只检查常见的属性。正如我所看到的,只有当它们都具有具有不同值的相同属性时,您的方法才有效。 Lodash is a utility library
标签: javascript node.js lodash