web-dev-qa-db-ja.com

オブジェクトの配列内の重複オブジェクトのリストを取得します

オブジェクトの配列内で重複するオブジェクトを取得しようとしています。オブジェクトが以下のようなものであるとしましょう。

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' }
];
5
ua_boaz

Lodashでは _.groupBy() を使用して、要素をidでグループ化できます。 _.filter() 2つ未満のメンバーを持つグループを除外し、 _.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>
1
Ori Drori

配列を使用して一意の要素を格納し、値にフィルターを使用して重複のみを返すことができます。

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;
})
0
Niall

これを試して

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/

0
Saurabh

関数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;
}
0
ControlAltDel

Lodashでこれを filter および countBy で解決すると、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))
0
Akrion