【问题标题】:How to find differences between n arrays of objects如何找到n个对象数组之间的差异
【发布时间】:2016-09-09 09:16:17
【问题描述】:

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

每个对象有 4 个属性:participation_enablednamepathing_enabledid,并且这些属性在其他数组中对于相同的属性 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 数组应包含以下对象:

[
  {id:"prop1", participation_enabled:["false","true"], pathing_enabled:["false","true"], index:0},
  {id:"prop2", participation_enabled:["false","true"], name:["User Status","Room"], participation_enabled:["false","true"], pathing_enabled:["false","true"], index:1},
  {id:"prop3", participation_enabled:["false","true"], name:["Initial ID","Phase","Trackingcode"], participation_enabled:["false","true"], pathing_enabled:["false","true"], index:2},
  {id:"prop4", name:["User ID","Custom Insight 4"], pathing_enabled:["false","true"], index:3}
]

非常感谢任何建议。

【问题讨论】:

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


    【解决方案1】:

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

    希望这会对您有所帮助。还可以添加一些错误处理。

    编辑 添加支持以使用 google 下划线方法。现在一切都应该工作了。 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);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 你知道如何在 Google Script 中包含下划线 JS 吗?
    • 嗯..该死的你在谷歌下划线脚本中没有mapObject(((让我说一下
    • 添加对使用谷歌下划线方法的支持..现在一切都应该工作了
    • 谢谢,它有效!我将等待 user3297291 编辑他的解决方案以确定哪个是最好的......
    【解决方案2】:

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

    【讨论】:

    • Google Script 无法识别 =&gt; ... 它给了我一个语法错误
    • 能否请您将代码编辑为 ES5(“经典风格”)?
    • 我已将箭头函数替换为常规函数。现在也应该在旧版本的 chrome 中工作...... ;)
    • 如果一个对象没有差异(如最后一个对象),那么它应该只包含id属性
    • 糟糕,我错过了这个要求。对于那个很抱歉。我注意到我也跳过了 index 道具。我现在没有时间把它们包括在内。以后可能会编辑这个。现在,我想您必须选择其他答案或自己包含这些要求..
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-12-28
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多