Javascript 对象数组的键值对交集
我想知道是否有一种方法可以找到对象数组中键值对的交集。假设您有一个由三个对象组成的数组,它们都具有相同的键,如下所示:Javascript 对象数组的键值对交集,javascript,object,intersection,Javascript,Object,Intersection,我想知道是否有一种方法可以找到对象数组中键值对的交集。假设您有一个由三个对象组成的数组,它们都具有相同的键,如下所示: arrayOfObj = [ { "a": 1, "b": "stringB" "c": {"c1":1, "c2": "stringC2" } }, { "a": 1, "b": "stringBdiff"
arrayOfObj = [
{
"a": 1,
"b": "stringB"
"c": {"c1":1,
"c2": "stringC2"
}
},
{
"a": 1,
"b": "stringBdiff"
"c": {"c1":1,
"c2": "stringC2"
}
},
{
"a": 1,
"b": "stringB"
"c": {"c1":1,
"c2": "stringC2"
}
}
]
我想找到三个对象的公共键值对:
output= [
{"a":1},
{"c": {"c1":1,
"c2":"stringC2"
}
}
]
这就是我到目前为止所做的,它对嵌套对象有效,但对嵌套对象无效。我想知道是否有一种更优雅的方法,也可以用于嵌套对象
let属性;
让共同发现=错误;
让notCommonFound=false;
常量commonValues=[];
让价值;
常量初始数组=[{
“a”:2,
“b”:“stringB”,
“c”:{
“c1”:1,
“c2”:“stringC2”
}
},
{
“a”:1,
“b”:“stringB”,
“c”:{
“c1”:2,
“c2”:“stringC2”
}
},
{
“a”:1,
“b”:“stringB”,
“c”:{
“c1”:2,
“c2”:“stringC2”
}
}
];
const commonStorage=[];
常量引用=初始数组[0];
属性=Object.keys(参考);
properties.forEach((属性)=>{
for(设i=0;i 对于(让j=0;j在我们实现intersect
之前,我们首先来看一下我们期望它的行为-
console.log
( intersect
( { a: 1, b: 2, d: 4 }
, { a: 1, c: 3, d: 5 }
)
// { a: 1 }
, intersect
( [ 1, 2, 3, 4, 6, 7 ]
, [ 1, 2, 3, 5, 6 ]
)
// [ 1, 2, 3, <1 empty item>, 6 ]
, intersect
( [ { a: 1 }, { a: 2 }, { a: 4, b: 5 }, ]
, [ { a: 1 }, { a: 3 }, { a: 4, b: 6 }, ]
)
// [ { a: 1 }, <1 empty item>, { a: 4 } ]
, intersect
( { a: { b: { c: { d: [ 1, 2 ] } } } }
, { a: { b: { c: { d: [ 1, 2, 3 ] } } } }
)
// { a: { b: { c: { d: [ 1, 2 ] } } } }
)
由于需要同时支持对象和数组,intersect1
的实现仍然相对复杂,map
、filter
和reduce
的顺序有助于维持程序流
const intersect1 = (left = {}, right = {}) =>
Object.entries (left)
.map
( ([ k, v ]) =>
// both values are objects
isObject (v) && isObject (right[k])
? [ k, intersect (v, right[k]) ]
// both values are "equal"
: v === right[k]
? [ k, v ]
// otherwise
: [ k, {} ]
)
.filter
( ([ k, v ]) =>
isObject (v)
? Object.keys (v) .length > 0
: true
)
.reduce
( assign
, isArray (left) && isArray (right) ? [] : {}
)
最后,我们实现了merge
,方法与我们在——
最终的依赖关系-
const isObject = x =>
Object (x) === x
const isArray =
Array.isArray
const assign = (o, [ k, v ]) =>
(o [k] = v, o)
验证以下浏览器中的完整程序是否正常工作-
const isObject=x=>
对象(x)==x
康斯特伊萨雷酒店=
Array.isArray
常数赋值=(o[k,v])=>
(o[k]=v,o)
常量合并=(左={},右={})=>
Object.entries(右)
.地图
([k,v])=>
isObject(v)和isObject(左[k])
?[k,合并(左[k],v)]
:[k,v]
)
.减少(分配,左)
const intersect=(左={},右={})=>
合并
(交叉点1(左、右)
,相交1(右,左)
)
常量intersect1=(左={},右={})=>
Object.entries(左)
.地图
([k,v])=>
isObject(v)和isObject(右[k])
?[k,相交(v,右[k])]
:v==右[k]
?[k,v]
:[k,{}]
)
.过滤器
([k,v])=>
等深线(v)
?对象键(v).长度>0
:对
)
减少
(指派
,isArray(左)和&isArray(右)?[]:{}
)
console.log
(相交
({a:1,b:2,d:4}
,{a:1,c:3,d:5}
)
//{a:1}
横断
( [ 1, 2, 3, 4, 6, 7 ]
, [ 1, 2, 3, 5, 6 ]
)
// [ 1, 2, 3, 6 ]
横断
([{a:1},{a:2},{a:4,b:5},]
,[{a:1},{a:3},{a:4,b:6},]
)
//[{a:1},{a:4}]
横断
({a:{b:{c:{d:[1,2]}}}
,{a:{b:{c:{d:[1,2,3]}}
)
//{a:{b:{c:{d:[1,2]}}
)
所以基本上你想删除重复项?试着阅读–我会做一个改编,在我有时间的时候更直接地回答这个问题:Ddo所有的对象都有相同的键,或者一些对象有不同的键。如果键都一样,你可以用lodash之类的东西来做深度相等检查。\isEqual(obj1、obj2)
。实际上,我想保留副本并删除所有其他内容。@duxfox--所有对象都具有完全相同的键和相同的键数。我不能使用深度相等,因为对象之间的某些值会不同,所以对象不会相等,但某些键值对可能相等。谢谢您的回答@user633183!但是是否可以修改unionAll以接受对象数组而不是对象或数组?在我的情况下,输入是包含对象的动态生成数组。@JordanA29当然,只需将const unionAll=(x=None,…xs)=>
更新为const unionAll=([x=None,…xs])=>
const merge = (left = {}, right = {}) =>
Object.entries (right)
.map
( ([ k, v ]) =>
isObject (v) && isObject (left [k])
? [ k, merge (left [k], v) ]
: [ k, v ]
)
.reduce (assign, left)
const isObject = x =>
Object (x) === x
const isArray =
Array.isArray
const assign = (o, [ k, v ]) =>
(o [k] = v, o)