获取对象数组中重复对象的列表

时间:2018-11-08 16:28:28

标签: javascript arrays typescript ecmascript-6 lodash

我正在尝试在对象数组中获取重复的对象,可以说对象如下。

  values = [
        { id:10; name: 'someName1' },
        { id:10; name: 'someName2' },
        { id:11; name: 'someName3' },
        { id:12; name: 'someName4' }
    ]

重复的对象应如下所示返回

 duplicate= [
        { id:10; name: 'someName1' },
        { id:10; name: 'someName2' }
    ]

8 个答案:

答案 0 :(得分:4)

您可以使用reduce根据id键创建计数器查询表,并使用filter删除仅出现一次的所有项目。时间复杂度为O(n)。

const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];

const lookup = values.reduce((a, e) => {
  a[e.id] = e.id in a ? ++a[e.id] : 0;
  return a;
}, {});

console.log(values.filter(e => lookup[e.id]));

答案 1 :(得分:3)

您尚未弄清两个ID不同但名称相同的对象是否被视为重复对象。我假设这些不算重复。换句话说,只有具有相同ID的对象才算作重复对象。

let ids = {};
let dups = [];

values.forEach((val)=> {
  if (ids[val.id]) {
    // we have already found this same id
    dups.push(val)
  } else {
    ids[val.id] = true;
  }
})
return dups;

答案 2 :(得分:1)

假设您拥有:

$('#upload_docu').on("change", function(){ readURL(this); });

<input class="file-upload-input" type='file' id="upload_docu" onclick="readURL(this);" accept="" />

<input class="file-upload-input" type='file' id="upload_docu" onchange="readURL(this);" accept="" />

因此,要获得独特的物品:

arr = [
    { id:10, name: 'someName1' },
    { id:10, name: 'someName2' },
    { id:11, name: 'someName3' },
    { id:12, name: 'someName4' }
]

然后,结果将是

unique = arr
     .map(e => e['id'])
     .map((e, i, final) => final.indexOf(e) === i && i)
     .filter(obj=> arr[obj])
     .map(e => arr[e]);

而且,要获取重复的ID:

unique = [
     { id:10, name: 'someName1' },
     { id:11, name: 'someName3' },
     { id:12, name: 'someName4' }
]

ID列表将

duplicateIds = arr
     .map(e => e['id'])
     .map((e, i, final) => final.indexOf(e) !== i && i)
     .filter(obj=> arr[obj])
     .map(e => arr[e]["id"])

因此,要获取重复的对象:

duplicateIds = [10]

现在您拥有了:

duplicate = arr.filter(obj=> dublicateIds.includes(obj.id));

感谢https://reactgo.com/removeduplicateobjects/

答案 3 :(得分:0)

尝试一下

function checkDuplicateInObject(propertyName, inputArray) {
  var seenDuplicate = false,
  testObject = {};

  inputArray.map(function(item) {
  var itemPropertyName = item[propertyName];    
  if (itemPropertyName in testObject) {
  testObject[itemPropertyName].duplicate = true;
  item.duplicate = true;
  seenDuplicate = true;
 }
 else {
   testObject[itemPropertyName] = item;
   delete item.duplicate;
 }
});

 return seenDuplicate;
}

引自:http://www.competa.com/blog/lets-find-duplicate-property-values-in-an-array-of-objects-in-javascript/

答案 4 :(得分:0)

创建一个函数objectsEqual,然后使用过滤器

values.filter(function(num, elem) {
  for (var i = 0; i < values.length; i++) {
    if (i == num) continue;
    if (objectsEqual(values[num], values[i])) return true;
  }
  return false;
}

答案 5 :(得分:0)

您可以使用数组存储唯一元素,并使用值过滤器仅返回重复项。

const unique = []

const duplicates = values.filter(o => {

   if(unique.find(i => i.id === o.id && i.name === o.name)) {
     return true
   }

   unique.push(o)
   return false;
})

答案 6 :(得分:0)

使用lodash,您可以使用_.groupBy()按元素id分组。超过_.filter()个成员少于两个的组,并_.flatten()个结果:

const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];

const result = _.flow([
  arr => _.groupBy(arr, 'id'), // group elements by id
  g => _.filter(g, o => o.length > 1), // remove groups that have less than two members
  _.flatten // flatten the results to a single array
])(values);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 7 :(得分:0)

使用lodash,您可以使用filtercountBy来解决O(n)的复杂性:

const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]

const counts = _.countBy(data, 'id')
console.log(_.filter(data, x => counts[x.id] > 1))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

您可以像这样对ES6做同样的事情:

const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]

const countBy = (d, id) => d.reduce((r,{id},i,a) => (r[id] = a.filter(x => x.id == id).length, r),{})
const counts = countBy(data, 'id')
console.log(data.filter(x => [x.id] > 1))