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)