【问题标题】:JavaScript array not filtering duplicate itemsJavaScript 数组不过滤重复项
【发布时间】:2018-01-18 03:03:09
【问题描述】:

我的数组过滤器不起作用,我不确定哪一部分出错了。我的样本数据:

var arr = [
    {accountID: '-KqIR-HT7orcPpe-lZa8', age: 31, gender: 'female'},
    {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'},
    {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'},
    {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'},
    {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'},
    {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female}
];

我想过滤掉相同的 accountID。我在网上找到了这个解决方案:

arr = arr.filter( function( item, index, inputArray ) {
   return inputArray.indexOf(item) == index;
});

当我尝试使用这个打印出过滤后的数组时:

for(var i = 0; i < arr.length; i++){
        console.log(arr[i][0].accountID + ' ' + arr[i][0].age + ' ' + arr[i][0].gender);
}

我得到了完全相同的数组,但结果重复。哪一部分错了?谢谢!

【问题讨论】:

  • arr 中的对象是否与inputArray 中的对象相同(字面意思相同,结构不同)?
  • 在我看来,您的过滤功能实际上并没有做任何事情。原始数组的每个元素都会调用一次回调;对于每个元素,它还传入该元素的索引。元素的索引将始终等于自身,因此我希望过滤器返回每个项目。
  • @MinusFour 对不起,我认为 inputArray 只是函数的一个参数?在这种情况下,它是正确的?
  • @Amy 是的,它在 for 循环那部分打印出完全相同的数组
  • 这些元素相等的条件是什么? accountID 相同或所有三个字段都相同。使用 inputArray.indexOf(item) == index 找不到重复项,因为数组中的每个对象都是唯一对象,即使它们具有相同的值。

标签: javascript arrays filter duplicates


【解决方案1】:

在 ES2015 中,您可以使用 Set() 来存储任何类型的唯一值。

以下示例使用 .forEach() 遍历数组中的每个值,并将唯一的值添加到辅助数组 uniq。请注意,您需要 stringifyparse 数组中的对象。

var arr = [{accountID: '-KqIR-HT7orcPpe-lZa8', age: 31, gender: 'female'}, {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'}, {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'}, {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender:
'female'}, {accountID: '-KqIR-GvEpHFiPFZRxbG', age: 59, gender: 'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender:
'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'}, {accountID: '-KqIR-EKbN02zAfCRyoe', age: 24, gender: 'female'}];

var uniq = new Set();
arr.forEach(e => uniq.add(JSON.stringify(e)));
var res = Array.from(uniq).map(e => JSON.parse(e));
console.log(res);

希望这会有所帮助! :)

【讨论】:

  • 喜欢头像:)
  • @Amy -- 我看到你的时候也是这么想的;)
  • 友谊加深
  • @ObsidianAge 非常感谢您的解释!我正要问你关于套装的问题,你用解释更新了解决方案!!非常感谢!!
  • 使用JSON.stringify 可能有效,但这是一个有风险的“解决方案”,无法保证 JavaScript 对象和 JSON 字符串中的属性顺序,因此您可以存储 {"accountID": "-KqIR-HT7orcPpe-lZa8", "age": "31", "gender": "female"}{"gender": "female", "accountID": "-KqIR-HT7orcPpe-lZa8", "age": "31"} 在集合中,即使它们应该被视为相同。 @DeniseTan
【解决方案2】:

请改用findIndex,因为这些对象都是不同的。

var arr = [{
    accountID: '-KqIR-HT7orcPpe-lZa8',
    age: 31,
    gender: 'female'
  },
  {
    accountID: '-KqIR-GvEpHFiPFZRxbG',
    age: 59,
    gender: 'female'
  },
  {
    accountID: '-KqIR-GvEpHFiPFZRxbG',
    age: 59,
    gender: 'female'
  },
  {
    accountID: '-KqIR-GvEpHFiPFZRxbG',
    age: 59,
    gender: 'female'
  },
  {
    accountID: '-KqIR-GvEpHFiPFZRxbG',
    age: 59,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  },
  {
    accountID: '-KqIR-EKbN02zAfCRyoe',
    age: 24,
    gender: 'female'
  }
];
arr = arr.filter(function(item, index, inputArray) {
  return inputArray.findIndex(el => el.accountID === item.accountID) == index;
});

console.log(arr);

您也可以为此使用Map

var arr = [{
        accountID: '-KqIR-HT7orcPpe-lZa8',
        age: 31,
        gender: 'female'
      },
      {
        accountID: '-KqIR-GvEpHFiPFZRxbG',
        age: 59,
        gender: 'female'
      },
      {
        accountID: '-KqIR-GvEpHFiPFZRxbG',
        age: 59,
        gender: 'female'
      },
      {
        accountID: '-KqIR-GvEpHFiPFZRxbG',
        age: 59,
        gender: 'female'
      },
      {
        accountID: '-KqIR-GvEpHFiPFZRxbG',
        age: 59,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      },
      {
        accountID: '-KqIR-EKbN02zAfCRyoe',
        age: 24,
        gender: 'female'
      }
    ];
    let m = new Map(arr.map(obj => [obj.accountID, obj]));
    let noDuplicates = [...m.values()];
    
    console.log(noDuplicates);

【讨论】:

  • 但是当我使用for循环打印出结果时,它只打印出'-KqIR-HT7orcPpe-lZa8'而没有重复。另外两个数据丢失了。
  • @DeniseTan,你是怎么打印出来的?此处的示例运行良好,它打印了所有 3 个 id。
  • 我使用了 console.log(arr) 以及有问题的 for 循环,但它只返回一个结果,即没有重复的结果。另一个有重复的只是被过滤掉]
  • 这个例子中没有for循环,当你运行sn-p它对你有用吗?
  • 是的,代码 sn-p 可以工作,但奇怪的是,当我将代码放入项目时,它只返回一条记录。
猜你喜欢
  • 1970-01-01
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 2017-03-25
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
相关资源
最近更新 更多