简体   繁体   中英

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. 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:

 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.

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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