Smarajit
Smarajit

Reputation: 173

Remove duplicate from array of objects based on value of properties in JavaScript

How can I remove duplicates from an array someArray like below based on the name property given the condition that if name is the same for two elements but for one them the type is new, the original one (without type new) will be retained?

someArray = [{id: 1, name:"apple"}, {id: 2, name:"mango"}, {id: 3, name:"apple", type: "new"}, {id: 4, name:"orange"}, {id: 5, name:"orange", type: "new"}, {id: 6, name: "pineapple", type: "new"}]

to

[{id: 1, name:"apple"}, {id: 2, name: "mango"}, {id: 4, name:"orange"}, {id: 6, name: "pineapple", type: "new"}]

Upvotes: 3

Views: 12504

Answers (6)

fonzane
fonzane

Reputation: 440

I like this approach

let uniqueIDs = new Set<string>();
return objectArr.filter(o => {
  if (uniqueIDs.has(o.id)) return false;
  uniqueIDs.add(o.id);
  return true;
});

Upvotes: 1

Harry Naruto
Harry Naruto

Reputation: 139

To remove the duplicates from an array of objects:

  1. Create an empty array that will store the unique object IDs.
  2. Use the Array.filter() method to filter the array of objects.
  3. Only include objects with unique IDs in the new array.
// ✅ If you need to check for uniqueness based on a single property
const arr = [
  {id: 1, name: 'Tom'},
  {id: 1, name: 'Tom'},
  {id: 2, name: 'Nick'},
  {id: 2, name: 'Nick'},
];

const uniqueIds = [];

const unique = arr.filter(element => {
  const isDuplicate = uniqueIds.includes(element.id);

  if (!isDuplicate) {
    uniqueIds.push(element.id);

    return true;
  }

  return false;
});

// 👇️ [{id: 1, name: 'Tom'}, {id: 2, name: 'Nick'}]
console.log(unique);

// ------------------------------------------------------------
// ------------------------------------------------------------
// ------------------------------------------------------------

// ✅ If you need to check for uniqueness based on multiple properties

const arr2 = [
  {id: 1, name: 'Tom'},
  {id: 1, name: 'Tom'},
  {id: 1, name: 'Alice'},
  {id: 2, name: 'Nick'},
  {id: 2, name: 'Nick'},
  {id: 2, name: 'Bob'},
];

const unique2 = arr2.filter((obj, index) => {
  return index === arr2.findIndex(o => obj.id === o.id && obj.name === o.name);
});

// [
//   { id: 1, name: 'Tom' },
//   { id: 1, name: 'Alice' },
//   { id: 2, name: 'Nick' },
//   { id: 2, name: 'Bob' }
// ]
console.log(unique2);

Upvotes: 3

Xupitan
Xupitan

Reputation: 1681

let someArray = [{id: 1, name:"apple"}, {id: 2, name:"mango"}, {id: 3, name:"apple", type: "new"}, {id: 4, name:"orange"}, {id: 5, name:"orange", type: "new"}, {id: 6, name: "pineapple", type: "new"}]
someArray.sort(function (a, b) {
  if (a.type !== 'undefined') return 1
  return 0
})
const result = someArray.reduce((resArr, currentArr) => {
  let other = resArr.some((ele) => currentArr.name === ele.name)
  if (!other) resArr.push(currentArr)
  return resArr
}, [])
console.log(result)

Upvotes: 0

Som Shekhar Mukherjee
Som Shekhar Mukherjee

Reputation: 8168

You can use Array.prototype.reduce and filter out the items that satisfy the condition.

const 
  input = [
    { id: 1, name: "apple" },
    { id: 2, name: "mango" },
    { id: 3, name: "apple", type: "new" },
    { id: 4, name: "orange" },
    { id: 5, name: "orange", type: "new" },
    { id: 6, name: "pineapple", type: "new" },
  ],
  output = Object.values(
    input.reduce((r, o) => {
      if (!r[o.name] || (r[o.name].type === "new" && o.type !== "new")) {
        r[o.name] = o;
      }
      return r;
    }, {})
  );

console.log(output);

You can also do it using the Spread Syntax.

const 
  input = [
    { id: 1, name: "apple" },
    { id: 2, name: "mango" },
    { id: 3, name: "apple", type: "new" },
    { id: 4, name: "orange" },
    { id: 5, name: "orange", type: "new" },
    { id: 6, name: "pineapple", type: "new" },
  ],
  output = Object.values(
    input.reduce(
      (r, o) =>
        !r[o.name] || (r[o.name].type === "new" && o.type !== "new")
          ? { ...r, [o.name]: o }
          : r,
      {}
    )
  );

console.log(output);

Upvotes: 5

Code Maniac
Code Maniac

Reputation: 37755

You can use Map to club values by name and in case there are two values with same name just use the one without type = "new"

let someArray = [{id: 3, name:"apple", type: "new"}, {id: 1, name:"apple"}, {id: 2, name:"mango"}, {id: 4, name:"orange"}, {id: 5, name:"orange", type: "new"}, {id: 6, name: "pineapple", type: "new"}]

function getUnique(arr){
  let mapObj = new Map()
  
  arr.forEach(v => {
    let prevValue = mapObj.get(v.name)
    if(!prevValue || prevValue.type === "new"){
      mapObj.set(v.name, v)
    } 
  })
  return [...mapObj.values()]
}

console.log(getUnique(someArray))

Upvotes: 6

Elvis Pimentel
Elvis Pimentel

Reputation: 370

You can iterate your array and evaluate if is 'type: new' and is not already existing, then pop out the item.

let someArray = [{
    id: 1,
    name: "apple"
}, {
    id: 2,
    name: "mango"
}, {
    id: 3,
    name: "apple",
    type: "new"
}, {
    id: 4,
    name: "orange"
}, {
    id: 5,
    name: "orange",
    type: "new"
}, {
    id: 6,
    name: "pineapple",
    type: "new"
}];
console.info('Initial value:' + JSON.stringify(someArray));
someArray.forEach(function(item, index, object) {
    if (item.type === 'new' && someArray.filter(val => val.name === item.name && !val.type)) {
        object.splice(index, 1);
    }
});

console.info('Desired Result:' + JSON.stringify(someArray));

Upvotes: 2

Related Questions