【问题标题】:Find duplicate values in objects with Javascript使用 Javascript 查找对象中的重复值
【发布时间】:2018-06-13 14:47:30
【问题描述】:

我一直在努力解决我遇到的问题。我有一个包含对象的数组,如下所示:

var array = [
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Hannah Reed",
    Country: "Scottland",
    Age: 23
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  }
];

我想根据要搜索的值获取其中具有重复值的对象。即,我想获取具有重复值“名称”和“年龄”但没有“国家”的对象,所以我最终会得到:

[
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  }
];

如果一直在尝试做

array.forEach(function(name, age){
  if(array.name == name || array.age == age){
    console.log(the result)
}
})

但这只检查对象的值是否等于它们自身。

谁能帮帮我?

【问题讨论】:

标签: javascript arrays function sorting


【解决方案1】:

您可以使用 2 个reduce。第一个是对数组进行分组。第二种是只包含超过 1 个元素的组。

var array = [{"name":"Steven Smith","Country":"England","Age":35},{"name":"Hannah Reed","Country":"Scottland","Age":23},{"name":"Steven Smith","Country":"England","Age":35},{"name":"Robert Landley","Country":"England","Age":84},{"name":"Steven Smith","Country":"England","Age":35},{"name":"Robert Landley","Country":"England","Age":84}]

var result = Object.values(array.reduce((c, v) => {
  let k = v.name + '-' + v.Age;
  c[k] = c[k] || [];
  c[k].push(v);
  return c;
}, {})).reduce((c, v) => v.length > 1 ? c.concat(v) : c, []);

console.log(result);

【讨论】:

  • 这太棒了!非常优雅,将此标记为答案,非常感谢:)
【解决方案2】:

我参加聚会有点晚了,但这可能会对面临同样问题的人有所帮助,因为我相信这是一个更易于理解的解决方案:

let duplicates = [];
array.forEach((el, i) => {
  array.forEach((element, index) => {
    if (i === index) return null;
    if (element.name === el.name && element.Age === el.Age) {
      if (!duplicates.includes(el)) duplicates.push(el);
    }
  });
});
console.log("duplicates", duplicates);

有两件事可能难以理解:

  • 使用 forEach,您可以提供第二个参数作为索引。这是为了确保我们不会相互比较相同的两个数组条目(如果 (i === index) 返回 null;-> 中止 forEach)
  • !duplicates.includes ("if not duplicates contains) 在将元素添加到重复数组之前进行检查,如果它已经存在。由于 {} === {} 在 JS 中为 false,因此“等于”不会有问题" 对象已经在重复数组中,但会简单地避免在一个 forEach 循环中两次添加相同的元素

编辑: 一个更好的解决方案是:

const duplicates = array
    .map((el, i) => {
        return array.find((element, index) => {
            if (i !== index && element.name === el.name && element.Age === el.Age) {
                return el
            }
        })
    })
    .filter(x => x)
console.log("dupliactes:", duplicates)

它没有副作用,所有逻辑都在一个 if 语句中。需要过滤器来排序未定义的实例。

【讨论】:

  • 不客气@NileshSutar。在查看了这篇文章后,我刚刚添加了一个更好的解决方案。
【解决方案3】:

我现在想出的快速答案:

   
let result = [];

for(let item of array)
{
    for(let checkingItem of array)
    {
      if(array.indexOf(item) != array.indexOf(checkingItem) &&
        (item.name == checkingItem.name || item.Age == checkingItem.Age))
      {
        if(result.indexOf(checkingItem) == -1)
        {
          result.push(checkingItem);
        }

      }
   }
}

console.log(result);

【讨论】:

    【解决方案4】:

    试试下面的sn-p。它通过它自己的元素循环数组(内循环)。第一个if 条件检查相同的元素(我们不希望在输出中出现),第二个if 是否匹配所需的条件以识别任何重复的对象。

    var array = [
    	{
    		name: "Steven Smith",
    		Country: "England",
    		Age: 35
    	},
    	{
    		name: "Hannah Reed",
    		Country: "Scottland",
    		Age: 23
    	},
    	{
    		name: "Steven Smith",
    		Country: "England",
    		Age: 35
    	},
    	{
    		name: "Robert Landley",
    		Country: "England",
    		Age: 84
    	},
    	{
    		name: "Steven Smith",
    		Country: "England",
    		Age: 35
    	},
    	{
    		name: "Robert Landley",
    		Country: "England",
    		Age: 84
    	}
    ];
    
    for(let obj of array){
    	for(let ele of array){
    		if(obj==ele)
    			continue;
    		if(ele.name===obj.name && ele.age===obj.age){
    			console.log(obj);
    			break;
    		}
    	}
    }

    【讨论】:

      【解决方案5】:

      这是一个替代解决方案,我将指出

      let array      = getData();                       // sets up data array
      let duplicates = array.filter(duplicatesOnly);    // filter out duplicates
      
      console.log( duplicates );                        // output to console
      
      
      
      /* ============================================================================= */
      
      
      // Returns true/false based on a duplicate object being found   
      function duplicatesOnly(v1, i1, self) {
        let ndx = self.findIndex(function(v2, i2) {
          // make sure not looking at the same object (using index to verify)
          // use JSON.stringify for object comparison
          return (i1 != i2 && JSON.stringify(v1) == JSON.stringify(v2))
        })
        return i1 != ndx && ndx != -1
      }
      
      
      // Use function hoisting to place trivial code at the bottom of example
      function getData() {
        return [{
            name: "Steven Smith",
            Country: "England",
            Age: 35
          },
          {
            name: "Hannah Reed",
            Country: "Scottland",
            Age: 23
          },
          {
            name: "Steven Smith",
            Country: "England",
            Age: 35
          },
          {
            name: "Robert Landley",
            Country: "England",
            Age: 84
          },
          {
            name: "Steven Smith",
            Country: "England",
            Age: 35
          },
          {
            name: "Robert Landley",
            Country: "England",
            Age: 84
          }
        ];
      }

      好处

      • 代码的核心是 3 行
      • 代码清晰
      • 易于维护

      费用

      • 性能
        • JSON.stringify 在每次迭代中对两个对象执行(非常昂贵)
        • 复杂度:O(N^2) -- 数组越大,它可能变得越慢

      注意事项


      • JSON.stringify 可以根据键顺序创建字符串,因此即使对象具有相同的键/值,在比较对象时,顺序也可能是一个因素——这可以被视为好处或成本
      • 这是一个使用filterfindIndex 的示例,重点不是提高效率。可以通过使用缓存并执行一次JSON.stringify 来改进它,或者通过更定制的东西完全避免它。

      【讨论】:

        猜你喜欢
        • 2021-11-14
        • 2016-06-26
        • 2014-08-21
        • 1970-01-01
        • 2018-12-18
        • 2014-08-08
        • 2017-12-26
        相关资源
        最近更新 更多