任意数量的对象的交叉

时间:2017-04-05 20:51:47

标签: javascript

我试图尽可能有效地找到任意数量的对象之间的交集。这些对象都包含其他子对象,每个子对象都存储在父对象的唯一键下。为了我的目的,可以安全地假设当将对象1上的子对象a与对象2上的子对象进行比较时,内容是相同的,所以我不在乎是否覆盖了另一个。到目前为止,这是我正在使用的解决方案,但我担心它不够有效:

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

对此有更有效的解决方案吗?是否有一个库来处理这个功能并且有效地运行它?是否有一个我不知道的功能?任何这些问题的答案将不胜感激。

2 个答案:

答案 0 :(得分:1)

你可以使用这个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; }




请注意,在对象上执行delete是一项代价高昂的操作,并且削弱了引擎可以寻求和应用的优化。

答案 1 :(得分:0)

如果没有测试样本数据,我无法告诉您这是否适合您的需求,但您可以试一试。

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