Javascript: Remove duplicates in array of objects using a single property

限于喜欢 提交于 2021-02-11 12:26:01

问题


I have object like this where 'id', is unique. I need to remove duplicates from the array of objects in javascript in any version less than ES5. I need to compare based on the id field and remove its duplicates.

Example:

Object = [
{id: id_one, value: value_one, label: ABC},
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

Output:

result = [
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

I tried logic like this,

function getDistValues(object) {
  var distObject = [];
  var tempIndex = [];
  var length = object.length;

  for (var i = 0; i < length; i++) {
    tempIndex.push(object[i].id);

    if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
      distObject.push(object[i]);
    }
  }

  return distObject;
}

It is only giving the first object. I tried like mapping the ids and comparing it but not worked.

Any help will be useful to me.


回答1:


It's because you are always adding the id to the tempIndex array, so it always thinks the current one is a duplicate. Try:

function getDistValues(object) {
  var distObject = [];
  var tempIndex = [];
  var length = object.length;

  for (var i = 0; i < length; i++) {    
    if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
      tempIndex.push(object[i].id);
      distObject.push(object[i]);
    }
  }

  return distObject;
}



回答2:


You could take a Set for id property and filter if the id is not in the set.

var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
    unique = array.filter((ids => ({ id }) => !ids.has(id) && ids.add(id))(new Set));

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

An approach for older JS versions

var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
    ids = {},
    unique = [],
    i;

for (i = 0; i < array.length; i++) {
    if (ids[array[i].id]) continue;
    unique.push(array[i]);
    ids[array[i].id] = true;
}

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



回答3:


Here's a solution using a reduce and an object

const input = [
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_three', value: 'value_three', label: 'ABX'},
{id: 'id_two', value: 'value_two', label: 'ABY'},
{id: 'id_four', value: 'value_four', label: 'ABD'}
]

const output = Object.values(
  input.reduce((memo, curr) => {
    memo[curr.id] = curr
    return memo
  }, {})
)

console.log(output)



回答4:


You can do it by storing the id into an object and check if the id already exists in the object. If exists that means you've taken the object before. If not then push the object into a new array.

This approach takes O(n) time as we check from an object with constant time.

var arr = [
    {id: 'id_one', value: 'value_one', label: 'ABC'},
    {id: 'id_one', value: 'value_one', label: 'ABC'},
    {id: 'id_three', value: 'value_three', label: 'ABX'},
    {id: 'id_two', value: 'value_two', label: 'ABY'},
    {id: 'id_four', value: 'value_four', label: 'ABD'}
];


function getDistValues(arr) {
	var hash = {};
    var uniqueArr = [];
    
	for (var i = 0, l = arr.length; i < l; i++) {
    	    if (hash[arr[i].id] === undefined) {
        	hash[arr[i].id] = 1;
                uniqueArr.push(arr[i]);
            }	
        }
    
    return uniqueArr;
}

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



回答5:


You can use reduce() method for array with Object.values for filter duplicates

const inputArray = [
    {id: 'id_one', value: 'value_one', label: 'ABC'},
    {id: 'id_one', value: 'value_one', label: 'ABC'},
    {id: 'id_three', value: 'value_three', label: 'ABX'},
    {id: 'id_two', value: 'value_two', label: 'ABY'},
    {id: 'id_four', value: 'value_four', label: 'ABD'}
    ]


      
const filterArray = (arr) => Object.values(arr.reduce(
  (acum, item) => {
    acum[item.id] = item
    return acum
  }, 
  {})
)

console.log(filterArray(inputArray))



回答6:


You are adding items to the tempIndex array before you check if they are there. Since you always add each, then it's implicit that when you do the check the item will already be there.

You have to inverse this - check if an item exists and then add it to tempIndex

var data = [
  {id: "id_one", value: "value_one", label: "ABC"},
  {id: "id_one", value: "value_one", label: "ABC"},
  {id: "id_three", value: "value_three", label: "ABX"},
  {id: "id_two", value: "value_two", label: "ABY"},
  {id: "id_four", value: "value_four", label: "ABD"}
];

function getDistValues(object) {
  var distObject = [];
  var tempIndex = [];
  var length = object.length;

  for (var i = 0; i < length; i++) {
    //check first
    var notSeen = tempIndex.indexOf(object[i].id) === -1;
    
    if (notSeen) {
      tempIndex.push(object[i].id);
      //add later
      distObject.push(object[i]);
    }
  }

  return distObject;
}

var result = getDistValues(data);

console.log(result);

In order to be more efficient, you can also use an object to keep the duplicate IDs - that will eliminate the need for another iteration over tempIndex every loop:

var data = [
  {id: "id_one", value: "value_one", label: "ABC"},
  {id: "id_one", value: "value_one", label: "ABC"},
  {id: "id_three", value: "value_three", label: "ABX"},
  {id: "id_two", value: "value_two", label: "ABY"},
  {id: "id_four", value: "value_four", label: "ABD"}
];

function getDistValues(object) {
  var distObject = [];
  //use object
  var tempIndex = {};
  var length = object.length;

  for (var i = 0; i < length; i++) {
    var notSeen = tempIndex[object[i].id] !== true;
    
    if (notSeen) {
      //mark as visited
      tempIndex[object[i].id] = true;
      distObject.push(object[i]);
    }
  }

  return distObject;
}

var result = getDistValues(data);

console.log(result);


来源:https://stackoverflow.com/questions/61016338/javascript-remove-duplicates-in-array-of-objects-using-a-single-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!