如何找到n个对象数组之间的差异

时间:2016-09-09 09:16:17

标签: javascript arrays google-apps-script javascript-objects

我有一个名为.settings的数组,其中包含props个带对象的数组,所有数组都包含相同数量的对象。

每个对象都有4个属性:nparticipation_enablednamepathing_enabled这些属性可以在其他数组中为相同的属性ID具有不同的值。

我的目标是找到其他对象数组中不同的所有对象属性,并将它们存储在另一个名为id的数组中。

我们采取以下示例:

diffs

对于上面的示例,[ [ {participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"}, {participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"}, {participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"}, {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"} ], [ {participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"}, {participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"}, {participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"}, {participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"}, {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"} ], [ {participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"}, {participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"}, {participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"}, {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"} ] ] 数组应包含以下对象:

diffs

任何建议都非常感谢。

3 个答案:

答案 0 :(得分:1)

不是最优雅的方式。但它使用下划线JS。

希望这会对你有所帮助。另外添加一些错误处理将是个好主意。

修改 添加支持以使用谷歌下划线方法。现在一切都应该有效。 https://sites.google.com/site/scriptsexamples/custom-methods/underscoregs#TOC-_values-Object-obj-

var a = [
  [
    {participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"}, 
    {participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"}, 
    {participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"}, 
    {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ], 
  [
    {participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"}, 
    {participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"}, 
    {participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"}, 
    {participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ], 
  [
    {participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"}, 
    {participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"}, 
    {participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"}, 
    {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ]
];
var diff = {};
a.forEach(function(val, i){
  //first just init start object
  if (i == 0) {
    val.forEach(function(v1, ind){
      diff[v1.id] = {};
      diff[v1.id].index = [ind];
      for (var key in v1) {
        diff[v1.id][key] = [v1[key]];
      }
    });
  }
  else {
    //for all other values add them into array and remove dups
    val.forEach(function(v1){
      var id = v1.id;
      for (var key in v1) {
        diff[id][key].push(v1[key]);
      }
    });
  }
});

//now finalize data removing all that have only unique values
for (var key in diff) {
  var nested = diff[key];
  var index = nested.index.pop();
  for (nestedKey in nested) {
    nested[nestedKey] =  _.filter(nested[nestedKey], function(item, pos) {
      return nested[nestedKey].indexOf(item) == pos;
    });
    
    if (nested[nestedKey].length < 2) {delete nested[nestedKey];}
    
  }
  diff[key].id = key;
  diff[key].index = index
  if (_.keys(diff[key]).length < 3) {delete diff[key];}
}

diff = _.values(diff);

console.log(diff);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

答案 1 :(得分:0)

一个纯粹的js例子。请注意,如果您可以确定所有属性都包含字符串,则可以使用基于对象属性的方法替换indexOf搜索,以更快地检查重复项。

重要假设:

  • 数组中的对象索引确定匹配的对象

var sampleData = [
  [
    {participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"}, 
    {participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"}, 
    {participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"}, 
    {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ], 
  [
    {participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"}, 
    {participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"}, 
    {participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"}, 
    {participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ], 
  [
    {participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"}, 
    {participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"}, 
    {participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"}, 
    {participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"}, 
    {participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
  ]
];

// Reduce an array of data arrays into one array of merged objects
function dataReducer (matches, current) {
  current.forEach(function(obj, i) {
    if (!matches[i]) {
      matches[i] = obj;
    } else {
      matches[i] = mergeObj(matches[i], obj);
    }
  });
  
  return matches;
};

// Merge two matching objects
function mergeObj(obj1, obj2) {
  Object.keys(obj1).forEach(function(key) {
    if (obj1[key] !== obj2[key]) {
      obj1[key] = [].concat(obj1[key]);
      
      if (obj1[key].indexOf(obj2[key]) == -1) {
        obj1[key].push(obj2[key]);
      }
    }
  });
  
  return obj1;
};

var result = sampleData.reduce(dataReducer, []);
console.log(result);

答案 2 :(得分:0)

检查以下代码。 可能这不是最佳方式,但它解决了这个问题。

var mainArray = [
  [{
    participation_enabled: "false",
    name: "PropEins",
    pathing_enabled: "true",
    id: "prop1"
  }, {
    participation_enabled: "false",
    name: "User Status",
    pathing_enabled: "false",
    id: "prop2"
  }, {
    participation_enabled: "false",
    name: "Initial ID",
    pathing_enabled: "false",
    id: "prop3"
  }, {
    participation_enabled: "false",
    name: "User ID",
    pathing_enabled: "false",
    id: "prop4"
  }, {
    participation_enabled: "false",
    name: "Subdomain",
    pathing_enabled: "false",
    id: "prop5"
  }],
  [{
    participation_enabled: "false",
    name: "PropEins",
    pathing_enabled: "false",
    id: "prop1"
  }, {
    participation_enabled: "false",
    name: "Room",
    pathing_enabled: "false",
    id: "prop2"
  }, {
    participation_enabled: "false",
    name: "Phase",
    pathing_enabled: "false",
    id: "prop3"
  }, {
    participation_enabled: "false",
    name: "Custom Insight 4",
    pathing_enabled: "false",
    id: "prop4"
  }, {
    participation_enabled: "false",
    name: "Subdomain",
    pathing_enabled: "false",
    id: "prop5"
  }],
  [{
    participation_enabled: "true",
    name: "PropEins",
    pathing_enabled: "true",
    id: "prop1"
  }, {
    participation_enabled: "true",
    name: "User Status",
    pathing_enabled: "true",
    id: "prop2"
  }, {
    participation_enabled: "true",
    name: "Trackingcode",
    pathing_enabled: "true",
    id: "prop3"
  }, {
    participation_enabled: "false",
    name: "User ID",
    pathing_enabled: "false",
    id: "prop4"
  }, {
    participation_enabled: "false",
    name: "Subdomain",
    pathing_enabled: "false",
    id: "prop5"
  }]
];

var resultArray = mainArray[0];
for (var i = 0; i < mainArray.length; i++) {
  var arrayTocheck = mainArray[i];
  for (var outer = 0; outer < resultArray.length; outer++) {
    row = resultArray[outer];
    if (i == 0) {
      row.participation_enabled = [];
      row.name = [];
      row.pathing_enabled = [];
    }
    for (var inner = 0; inner < resultArray.length; inner++) {
      var rowtoCheck = arrayTocheck[inner];
      if (row.id == rowtoCheck.id) {
        if (!row.participation_enabled.includes(rowtoCheck.participation_enabled) && rowtoCheck.participation_enabled != "") {

          row.participation_enabled.push(rowtoCheck.participation_enabled);
        }
        if (!row.name.includes(rowtoCheck.name) && rowtoCheck.name != "") {
          row.name.push(rowtoCheck.name);
        }
        if (!row.pathing_enabled.includes(rowtoCheck.pathing_enabled) && rowtoCheck.pathing_enabled != "") {
          row.pathing_enabled.push(rowtoCheck.pathing_enabled);
        }
        break;
      }
    }
    resultArray[outer] = row;
  }


}
console.log(resultArray);