【问题标题】:javascript array filter duplicates by object keyjavascript数组过滤器按对象键重复
【发布时间】:2018-07-17 20:09:27
【问题描述】:

我在 Javascript 中有一个对象数组

我正在尝试按对象值过滤重复项

  1. 获取副本

  2. 变得独一无二

示例数组:

let array = [
{ 
    id: '001',
    name: 'aaa',
    type_id: 'a111'
},{ 
    id: '002',
    name: 'bbb',
    type_id: 'a111'
},{
    id: '003',
    name: 'ccc',
    type_id: 'a222'
},{
    id: '004',
    name: 'ddd',
    type_id: 'a333'
}];

这就是我希望我的数组变成的样子:

function 1(array, 'type_id')
[{ 
    id: '001',
    name: 'aaa',
    type_id: 'a111'
},{ 
    id: '002',
    name: 'bbb',
    type_id: 'a111'
}];

function 2(array, 'type_id')
[{ 
    id: '003',
    name: 'ccc',
    type_id: 'a222'
},{ 
    id: '004',
    name: 'ddd',
    type_id: 'a333'
}];

【问题讨论】:

  • 请使用<> 分享您作为工作人员的尝试,展示您遇到的问题。
  • 听起来你需要使用过滤器
  • 说:“这就是我希望我的数组变成的样子”但是给出了一个 not 数组的例子。

标签: javascript arrays filter ecmascript-6


【解决方案1】:

您可以将Map 用于相同的type_id 并收集对象,然后根据数组的长度将映射的项目推送到唯一或欺骗。

线

map.forEach(a => [unique, dupes][a.length - 1 && 1].push(...a));

获取地图并迭代它的所有元素并使用uniquedupes的目标数组,

                 [unique, dupes]                                 // targets

取映射数组的长度,用于分隔目标数组

                                [a.length - 1 && 1]              // select target

考虑此列表以获取索引,0 用于唯一项,1 用于重复项。零长度不存在,因为如果创建了映射条目,则长度为一。

length  length - 1  length - 1 && 1  comment
------  ----------  ---------------  --------
   1         0             0         take `length - 1`, because of falsy 1st operand
   2         1             1         take 2nd operand
   3         2             1         take 2nd operand
   4         3             1         take 2nd operand for all other greater length

然后使用spread syntax ...,数组a的所有项都用作Array#push的参数。

                                                   .push(...a)   // push all itmes of array

var array = [{ id: '001', name: 'aaa', type_id: 'a111' }, { id: '002', name: 'bbb', type_id: 'a111' }, { id: '003', name: 'ccc', type_id: 'a222' }, { id: '004', name: 'ddd', type_id: 'a333' }],
    key = 'type_id',
    map = new Map,
    unique = [],
    dupes = [];

array.forEach(o => map.set(o[key], (map.get(o[key]) || []).concat(o)));
map.forEach(a => [unique, dupes][a.length - 1 && 1].push(...a));

console.log(unique);
console.log(dupes);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 嗨!您能否为您的答案添加一些解释?我不明白你在这里做了什么:map.forEach(a => [unique, dupes][a.length - 1 && 1].push(...a));。 PS:我对此比较陌生。在此先感谢:)
【解决方案2】:

我已经编写了一些代码来完成您想要实现的目标:

let array = [{
  id: '001',
  name: 'aaa',
  type_id: 'a111'
}, {
  id: '002',
  name: 'bbb',
  type_id: 'a111'
}, {
  id: '003',
  name: 'ccc',
  type_id: 'a222'
}, {
  id: '004',
  name: 'ddd',
  type_id: 'a333'
}];

var duplicates = [];
var uniques = [];
var valueCounts = {};


function getDuplicatesAndUniques(array, value) {
  for (var i = 0; i < array.length; i++) {
    if (!valueCounts[array[i][value]])
      valueCounts[array[i][value]] = 1;
    else
      valueCounts[array[i][value]]++;
  }

  for (var i = 0; i < array.length; i++) {
    if (valueCounts[array[i][value]] == 1) {
      uniques.push(array[i]);
    } else {
      duplicates.push(array[i]);
    }
  }

}

getDuplicatesAndUniques(array, "type_id");

console.log(duplicates);
console.log(uniques);

https://jsfiddle.net/hbpx08xh/1/

希望这会有所帮助! :)

最好的问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2022-07-12
    • 2012-09-23
    • 2023-01-02
    • 2019-01-26
    • 1970-01-01
    • 2018-10-20
    • 2020-08-15
    相关资源
    最近更新 更多