【问题标题】:Delete duplicated elements in array of objects Javascript [closed]删除对象数组中的重复元素Javascript [关闭]
【发布时间】:2018-05-30 00:08:16
【问题描述】:

基本上我想知道如何在 JavaScript 中清理对象数组。

我已经看到一些示例显示如何根据一个元素的值来执行此操作,我需要它是通用的。这意味着它不依赖于孩子的名字。

Example of the way i don't want

我需要的是一个可以独立于对象结构工作的函数。

例如,它可以与这个一起工作:

object = [
    {value: 'value', configuration: 'configuration'},
    {value: 'value2', configuration: 'configuration2'},
    {value: 'value', configuration: 'configuration'},
]

//returning:

object = {
    {value: 'value', configuration: 'configuration'},
    {value: 'value2', configuration: 'configuration2'}
}

它也可以用于:

object = [
    {name: 'name', property: 'property'},
    {name: 'name2', property: 'property2'},
    {name: 'name', property: 'property'},
]

//returning:

object = [
    {name: 'name', property: 'property'},
    {name: 'name2', property: 'property2'}
]

【问题讨论】:

  • 有多种删除重复项的方法,其时间和空间复杂度各不相同
  • 对象可以包含各种类型的嵌套对象(地图、集合、日期、您自己的类实例、函数、正则表达式、HTML DOM 节点,...),并具有循环引用(具有父对象作为属性值;或对父对象/数组中另一个对象的交叉引用)。在这种情况下,您认为重复的内容变得非常模糊。请为您的问题提供明确的界限。您的第一段还谈到了对象数组,但代码示例使用了无效的语法。
  • 您的对象是否只包含字符串、数字、数组、对象、布尔值?没有功能和日期?
  • 仅供参考,您的代码不包含有效语法。那些object = {...} 应该是对象数组吗?
  • @CoryDanielson 它将包含对象...感谢您的更正。

标签: javascript arrays object filter


【解决方案1】:

使用filter/findIndex 技巧对数组进行重复数据删除很简单,唯一的问题是我们需要一个相等函数来比较元素。对于对象,简单的=== 不起作用。

这是一个使用基本浅等于比较器的简单示例。它只检查两个对象是否具有相同键的相同值,这将适用于您示例中的对象(但不适用于嵌套对象)。根据您的用例,这可能还不够。另一个不错的选择是 lodash 的 _.isEqual 方法,或者比较它们的 JSON 字符串的函数。 重要的是您定义一个函数来比较两个满足您要求的对象

var array1 = [
    {value: 'value', configuration: 'configuration'},
    {value: 'value2', configuration: 'configuration2'},
    {value: 'value', configuration: 'configuration'},
];

var array2 = [
    {name: 'name', property: 'property'},
    {name: 'name2', property: 'property2'},
    {name: 'name', property: 'property'},
];

// You need to define an equality function to use with the deduplicator. Heres a basic one.
function isKVEqual(obj1, obj2) {
  // Get the keys of these objects, make sure they have the same number of keys.
  const o1keys = Object.keys(obj1);
  const o2keys = Object.keys(obj2);
  if (o1keys.length !== o2keys.length) return false;
  
  // Check that the value of each key is the same in each object.
  for (const key of o1keys) {
    if (obj2[key] !== obj1[key]) return false;
  }
  
  return true;
}

// Deduplicate:
// Make sure to replace the isKVEqual call with whatever custom comparator you want to use.
const dedupedArray1 = array1.filter((item, index, list) => list.findIndex(x => isKVEqual(x, item)) === index);
const dedupedArray2 = array2.filter((item, index, list) => list.findIndex(x => isKVEqual(x, item)) === index);

console.log(dedupedArray1)
console.log(dedupedArray2)

【讨论】:

    【解决方案2】:

    如果您愿意使用外部库,我建议您使用 lodash 检查这两个项目是否重复,并通过这种方式进行过滤:

    let object = [
        {name: 'name', property: 'property'},
        {name: 'name2', property: 'property2'},
        {name: 'name', property: 'property'},
    ]
    
    function removeDuplicates(arr) {
      return arr.filter((elem, idx) => {
        return !arr.slice(idx + 1).find((other) => _.isEqual(elem, other));
      });
    }
    
    console.log(removeDuplicates(object));
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>

    【讨论】:

      【解决方案3】:

      您可以使用过滤器和json进行通用检查

      var list = [
          {value: 'value', configuration: 'configuration'},
          {value: 'value2', configuration: 'configuration2'},
          {value: 'value', configuration: 'configuration'},
      ];
      //filter element
      list = list.filter(function(value, index){
        var exists = false;
        //verify if exists the same element with other index before
        for(var i in list){
          //generic verify the json
          if(JSON.stringify(list[i]) ==         JSON.stringify(list[index]) && i < index){            exists = true; 
             break;
          }
        }  
        //if dont exists dont filter
        return !exists;
      });
      
      console.log(list);

      您可以使用自定义比较代替 JSON.stringfy

      function isEqual(a, b){
      
      for(var i in a)
             if(a[i] != b[i])
                return false;
        for(var i in b)
             if(b[i] != a[i])
                return false;
        return true;
      }
      

      因为 JSON.stringfy 为

      生成不同的字符串
      {value: 'value', configuration: 'configuration'},
      

      { configuration: 'configuration', value: 'value'},
      

      【讨论】:

        猜你喜欢
        • 2015-10-04
        • 1970-01-01
        • 1970-01-01
        • 2018-03-29
        • 2017-03-21
        • 1970-01-01
        • 1970-01-01
        • 2019-07-13
        • 1970-01-01
        相关资源
        最近更新 更多