0

I have an Array with duplicate objects, and I want to remove those duplicate objects. But I can't seem to find a proper solution for it. What is my mistake over here?

The object is as below.

{name: "login", text: "Login"}
{name: "navigation", text: "Navigation"}
{name: "landing", text: "Landing Page"}
{name: "login", text: "Login"}
{name: "navigation", text: "Navigation"}
{name: "landing", text: "Landing Page"}

Below is my code where items has the array of objects.

this.subMenuItems = this.items.reduce((acc, current) => {
  const x = acc.find(item => item.name === current.name);
  if (!x) {
    return acc.concat([current]);
  } else {
    return acc;
  }
}, []);

Also you can refer the screenshot of the Console.log of the items variable enter image description here

oni3619
  • 153
  • 1
  • 9
  • 3
    Does this answer your question? [How to remove all duplicates from an array of objects?](https://stackoverflow.com/questions/2218999/how-to-remove-all-duplicates-from-an-array-of-objects) – Heretic Monkey Apr 05 '21 at 17:27
  • I tried this exact same code in the browser console and it works perfectly fine. Can you share some more code from your Angular component, since I believe that the issue is to be found somewhere else – kevlatus Apr 05 '21 at 17:59
  • Do not reinvent the wheel. Have a look at lodash uniqBy: https://stackoverflow.com/questions/31740155/lodash-remove-duplicates-from-array You can specifically install lodash.uniqBy instead of importing the whole lib: https://www.npmjs.com/package/lodash.uniqby That way to achieve your desired output with a very well tested code which probably has more capabilities. – monogate Apr 05 '21 at 20:07
  • @HereticMonkey, some help from that and some help from this question got me a solution. – oni3619 Apr 06 '21 at 07:42

4 Answers4

4

This one will assign this.subMenuItems an array containing only the first instance of each item because indexOf returns the first index where the object is found.

this.subMenuItems = this.items.filter((item, index, self) => self.indexOf(item) === index);
Isaac
  • 184
  • 9
1

Problem

The problem with your code is that find will always return a defined value because there is atleast one object satisfying the condition (current object itself)

Solution

One solution is the solution which @Issac gave. It's time and space complexities are O(n^2) and O(1) resp.

There is one more solution with time and space complexities O(n) and O(n) resp.

function removeDuplicates(objects) {
  const map = new Map()

  for (const obj of objects) {
    map.put(obj.name, obj)
  }

  return map.values()
}
Shivam Singla
  • 2,117
  • 1
  • 10
  • 22
0

please find below a function that can return the list of duplicates or a list that removes duplicates.

identifyDuplicates(data: Object[], key: string, unique: boolean = 
true) {
    const unique: Object[] = [];
    const duplicates = data.filter(x => {
        if (unique.length > 0 && (unique?.find(u => u[key] == x[key]) != null)) 
    {  return true; }
        unique.push(x);
        return false;
    });
    return unique ? unique : duplicates;
}

it can be called in two ways:

public getUnique(data: Object[], key: string) {
    return this.identifyDuplicates(data, key);
}

public getDuplicate(data: Object[], key: string) {
    return this.identifyDuplicates(data, key, false);
}

for your case:

const unique = this.getUnique(this.subMenuItems, 'name');
console.log(JSON.stringify(unique ));

if you want to get the duplicate items

const duplicates = this.getDuplicate(this.subMenuItems, 'name');
console.log(JSON.stringify(duplicates));
RED-ONE
  • 167
  • 1
  • 5
-1
function solve(items) {
    var m = {}
    items.forEach((obj) => {
        var name = obj.name;
        var text = obj.text;
        if (!m[name]) {
            m[name] = new Set();
        }
        m[name].add(text);

    });
    var finalItemsList = [];
    Object.keys(m).forEach((name) => {
        Array.from(m[name]).forEach((text) => {
            finalItemsList.push({
                "name": name,
                "text": text
            })
        });

    });
    return finalItemsList;

}
console.log(items);
Gopi krishna
  • 308
  • 1
  • 9