简体   繁体   English

任意数量的对象的交集

[英]Intersection of an arbitrary number of objects

I am trying to find, as efficiently as possible, the intersection between an arbitrary number of objects. 我试图尽可能有效地找到任意数量的对象之间的交集。 Those objects all contain other sub-objects, each sub-object being stored under a unique key on the parent. 这些对象都包含其他子对象,每个子对象都存储在父对象的唯一键下。 For my purposes it is safe to assume that when comparing sub-object a on object 1 to sub-object a on object 2, the contents are the same so I do not care if one overwrites the other. 出于我的目的,可以安全地假设将对象1上的子对象a与对象2上的子对象a进行比较时,内容相同,因此我不在乎一个对象是否覆盖另一个对象。 So far this is the solution I am working with, but I am afraid it is not efficient enough: 到目前为止,这是我正在使用的解决方案,但恐怕它不够有效:

function intersectObjects(...objects){
  /*NOTE: This function will overwrite values on duplicate keys*/
  var returnObj; //temp variable to store the return value
  objects.forEach((obj, i) => {
    //on the first loop store my object
    if (i == 0) returnObj = obj;
    else {
      //Get an array of all properties currently being returned
      const returnProps = Object.getOwnPropertyNames(returnObj);
      //Loop over the properties array
      returnProps.forEach((propKey, j) => {
        //If the current property does not exist on the return object
        //Then delete the property on the return object
        if(!obj[returnProps[j]]) delete returnObj[returnProps[j]];
      });
    }
  });
  return returnObj;
}

Is there a more efficient solution for this? 有没有更有效的解决方案? Is there a library that handles this function and functions like it efficiently? 是否有一个库可以有效处理此功能和类似的功能? Is there a function that does this that I am not aware of? 有我不知道的功能吗? Answers to any of these questions would be appreciated. 对任何这些问题的答案将不胜感激。

You could use this ES6 function, which does not mutate any of the input objects, but returns a new one: 您可以使用此ES6函数,该函数不会突变任何输入对象,而是返回一个新的对象:

 function intersectObjects(...objects) { return !objects.length ? {} : Object.assign(...Object.keys(objects[0]).filter( key => objects.every( o => key in o ) ).map( key => ({ [key]: objects[0][key]}) )); } // Sample run var data = [ { a: 1, b: 2, c: 3, d: 4, e: 5}, { b: 2, c: 3, d: 4, e: 5, f: 6}, { a: 1, b: 2, d: 4, e: 5}, { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7} ]; var result = intersectObjects(...data); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Note that executing delete on an object is a costly operation, and cripples the optimisation that engines can otherwise seek and apply. 请注意,对对象执行delete操作是一项昂贵的操作,并且会破坏引擎原本可以寻求和应用的优化。

Without having sample data to test with, I can't tell you if this will work for your needs or not, but you can give it a shot. 如果没有可供测试的样本数据,我无法告诉您这是否可以满足您的需求,但是您可以尝试一下。

function intersectObjects(...objects) {
    return Object.assign.apply(null, objects);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM