代码之家  ›  专栏  ›  技术社区  ›  JilReg

在Javascript/Typescript中从数组中删除重复的子对象

  •  0
  • JilReg  · 技术社区  · 5 年前

    我有一个满是物体的阵列。几乎所有对象都有不同数量的键-值对。其中一些对象具有相同的键值对。

    有没有一个很好的方法来删除所有的子对象副本?(子对象复制=和 全部的 可以在另一个对象中找到键值对。)

    例如,在下面的示例中,它将删除所有中间对象,只保留第一个和最后一个对象。

    非常感谢:)

    我最接近的是从 here ,但我不知道如何添加if条件,以便只检查属性是否存在。

    由多个属性(id和名称)唯一

    arr.filter((v,i,a)=>a.findIndex(t=>(t.id === v.id && t.name===v.name))===i)
    

    输入

    input = [
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key3": "value1",
          "key4": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key3": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key3": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value2",
          "key3": "value2",
          "key4": "value2",
          "key5": "value2",
          "key6": "value2"
        },
      {
        "key0": {
          "key1": "value2",
          "key2": "value2",
          "key3": "value2",
          "key4": "value2",
          "key5": "value2",
          "key6": "value2"
        }
      }
    ]
    
    

    预期产量

    output = [
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key3": "value1",
          "key4": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value2",
          "key2": "value2",
          "key3": "value2",
          "key4": "value2",
          "key5": "value2",
          "key6": "value2",
        }
      }
    ]
    
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   guillaumepotier    5 年前

    这里有一个非常基本的O(n2)复杂溶液:

    var input = [
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key3": "value1",
          "key4": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key3": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key3": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value1",
          "key5": "value1"
        }
      },
      {
        "key0": {
          "key1": "value1",
          "key2": "value2",
          "key3": "value2",
          "key4": "value2",
          "key5": "value2",
          "key6": "value2"
        }
      },
      {
        "key0": {
          "key1": "value2",
          "key2": "value2",
          "key3": "value2",
          "key4": "value2",
          "key5": "value2",
          "key6": "value2"
        }
      }
    ];
    
    var isIncluded = function (a, b) {
    	for (var key in a) {
      	if (!b[key] || b[key] !== a[key])
        	return false;
      }
      
      return true;
    };
    
    
    var output = [];
    
    for (var i = 0; i < input.length; i++) {
    	var toInclude = true;
    
      for (var j = 0; j < input.length; j++) {
      	if (j === i)
        	continue;
          
        if (isIncluded(input[i].key0, input[j].key0)) {
        	toInclude = false;
          break;
        }
      }
      
      if (!toInclude)
      	continue;
        
      output.push(input[i]);
    }
    
    console.log(output);
    // document.write(JSON.stringify(output));

    请注意,由于您可能在其中一个对象中犯了错误(混合了value1和value2),因此输出得到3项

        2
  •  0
  •   mplungjan Gvidas    5 年前

    这里有一个解决方案,可以用elem处理每个数组 {key0:{}},... 你需要的格式。下面的eg处理的不仅仅是 value1 value2 :不管值多少!:)

    let input = [ { "key0": { "key1": "value1", "key2": "value1", "key3": "value1", "key4": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key3": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key2": "value1", "key3": "value1" } }, { "key0": { "key1": "value1", "key2": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key2": "value2", "key3": "value2", "key4": "value2", "key5": "value2", "key6": "value2" } }, { "key0": { "key1": "value2", "key2": "value2", "key3": "value2", "key4": "value2", "key5": "value2", "key6": "value2" } } ];
    
    function format(input) {
    
      let output = input.map(el => Object.keys(el)).map(ell => ell[0]);
    
      //check if only 'key0' at root key
      let same = output.reduce((acc, curr) => acc == curr ? output[0] : false, output[0]) == output[0];
      if (!same) return;
    
      //list all possibles value (value1, value2, ...)
      let possibleVal = {};
      for (key in input) {
        for (sub in input[key]['key0']) {
          possibleVal[input[key]['key0'][sub]] = null;
        }
      }
      possibleVal = Object.keys(possibleVal); // make it an array
    
      // fill output with possible values as key and fill with all possible values
      output = {};
      possibleVal.map(el => output[el] = {});
      input.map(el => {
        Object.entries(el['key0']).map(ell => {
          let key = ell[0];
          let value = ell[1]
          output[value][key] = value;
        });
      });
    
      // format it correctly and return it
      return possibleVal.map(val => ({
        'key0': output[val]
      }));
    }
    
    let final = format(input);
    
    console.log(JSON.stringify(final, null, 4));