'How to remove duplicate object in javascript?

I have object like this :

cons data = []
const result =
[
    {
        "result_id": "AAA877",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAA877",
                "hashtag_id": 1,
                "apptype_id": 3,
                "tag": {
                    "id": 1,
                    "name": "NodeJs",
                    "hashtag_group_id": 1
                }
            }
        ]
    },
    {
        "result_id": "AAAAA1",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAAAA1",
                "hashtag_id": 1,
                "apptype_id": 4,
                "tag": {
                    "id": 1,
                    "name": "NodeJs",
                    "hashtag_group_id": 1
                }
            }
        ]
    },
    {
        "result_id": "AAB238",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAB238",
                "hashtag_id": 2,
                "apptype_id": 4,
                "tag": null
            }
        ]
    },
    {
        "result_id": "AAB415",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAB415",
                "hashtag_id": 1,
                "apptype_id": 3,
                "tag": {
                    "id": 1,
                    "name": "NodeJs",
                    "hashtag_group_id": 1
                }
            }
        ]
    },
    {
        "result_id": "AAD668",
        "emp_id": 2,
        "hashtag": [
            {
                "result_id": "AAD668",
                "hashtag_id": 1,
                "apptype_id": 3,
                "tag": {
                    "id": 1,
                    "name": "NodeJs",
                    "hashtag_group_id": 1
                }
            }
        ]
    },
    {
        "result_id": "AAG239",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAG239",
                "hashtag_id": 4,
                "apptype_id": 3,
                "tag": null
            }
        ]
    },
    {
        "result_id": "AAH740",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAH740",
                "hashtag_id": 2,
                "apptype_id": 3,
                "tag": null
            }
        ]
    },
    {
        "result_id": "AAK119",
        "emp_id": 2,
        "hashtag": [
            {
                "result_id": "AAK119",
                "hashtag_id": 1,
                "apptype_id": 4,
                "tag": {
                    "id": 1,
                    "name": "NodeJs",
                    "hashtag_group_id": 1
                }
            }
        ]
    },
    {
        "result_id": "AAK298",
        "emp_id": 1,
        "hashtag": [
            {
                "result_id": "AAK298",
                "hashtag_id": 2,
                "apptype_id": 3,
                "tag": null
            }
        ]
    }
]

I want to filter and push emp_id and apptype_id without a duplicate

This is what i expected :

[
  { emp_id: 1, app_type_id: 3 },
  { emp_id: 1, app_type_id: 4 },
  { emp_id: 2, app_type_id: 3 },
  { emp_id: 2, app_type_id: 4 }
]

I was trying like this :

result.forEach(r => {
        if (r.hashtag[0].tag !== null) {
          const t = {
            emp_id: r.emp_id,
            app_type_id: r.hashtag[0].apptype_id
          }
          if (data.indexOf(t) === -1) {
            data.push(t)
          }
        }
      })

But what i got was like this :

[
  { emp_id: 1, app_type_id: 3 },
  { emp_id: 1, app_type_id: 4 },
  { emp_id: 1, app_type_id: 3 },
  { emp_id: 2, app_type_id: 3 },
  { emp_id: 2, app_type_id: 4 }
]

How to filter without a duplicate like what i expected ?

Please ask me if you need more information if it's still not enough



Solution 1:[1]

An alternative approach. Loop over the data, destructure the properties you want into a new object, stringify that, and push that string into a temporary array. Then, on every next iteration, check to see if that string has already been created. If it hasn't push that string into the array.

Finally map over the strings and parse each one to produce an array of objects that matches your expected output.

const data=[{result_id:"AAA877",emp_id:1,hashtag:[{result_id:"AAA877",hashtag_id:1,apptype_id:3,tag:{id:1,name:"NodeJs",hashtag_group_id:1}}]},{result_id:"AAAAA1",emp_id:1,hashtag:[{result_id:"AAAAA1",hashtag_id:1,apptype_id:4,tag:{id:1,name:"NodeJs",hashtag_group_id:1}}]},{result_id:"AAB238",emp_id:1,hashtag:[{result_id:"AAB238",hashtag_id:2,apptype_id:4,tag:null}]},{result_id:"AAB415",emp_id:1,hashtag:[{result_id:"AAB415",hashtag_id:1,apptype_id:3,tag:{id:1,name:"NodeJs",hashtag_group_id:1}}]},{result_id:"AAD668",emp_id:2,hashtag:[{result_id:"AAD668",hashtag_id:1,apptype_id:3,tag:{id:1,name:"NodeJs",hashtag_group_id:1}}]},{result_id:"AAG239",emp_id:1,hashtag:[{result_id:"AAG239",hashtag_id:4,apptype_id:3,tag:null}]},{result_id:"AAH740",emp_id:1,hashtag:[{result_id:"AAH740",hashtag_id:2,apptype_id:3,tag:null}]},{result_id:"AAK119",emp_id:2,hashtag:[{result_id:"AAK119",hashtag_id:1,apptype_id:4,tag:{id:1,name:"NodeJs",hashtag_group_id:1}}]},{result_id:"AAK298",emp_id:1,hashtag:[{result_id:"AAK298",hashtag_id:2,apptype_id:3,tag:null}]}];

const temp = [];

for (const obj of data) {
  const { emp_id, hashtag: [{ apptype_id }] } = obj;
  const newObj = { emp_id, app_type_id: apptype_id };
  const str = JSON.stringify(newObj);
  if (!temp.includes(str)) temp.push(str);
}

const out = temp.map(str => JSON.parse(str));
console.log(out);

Solution 2:[2]

I would run a filter on the objects that you have before extracting the info! This should do the trick:

var removed_duplicates = result.filter((result, index, self) =>
    index === self.findIndex((other_entry) => 
        (other_entry.emp_id === result.emp_id && 
         other_entry.hashtag[0].apptype_id === result.hashtag[0].apptype_id)))

What this does is it filters your original entries by looking for other entries in the list with the same values that you're trying to filter on. If there are none, then the returned index will be the same, otherwise it will succeed for the first encounter with one of the duplicate entries but fail for all of the following ones, causing them to be removed.

Solution 3:[3]

You could get an array of objects and filter with a Set.

const
    data = [{ result_id: "AAA877", emp_id: 1, hashtag: [{ result_id: "AAA877", hashtag_id: 1, apptype_id: 3, tag: { id: 1, name: "NodeJs", hashtag_group_id: 1 } }] }, { result_id: "AAAAA1", emp_id: 1, hashtag: [{ result_id: "AAAAA1", hashtag_id: 1, apptype_id: 4, tag: { id: 1, name: "NodeJs", hashtag_group_id: 1 } }] }, { result_id: "AAB238", emp_id: 1, hashtag: [{ result_id: "AAB238", hashtag_id: 2, apptype_id: 4, tag: null }] }, { result_id: "AAB415", emp_id: 1, hashtag: [{ result_id: "AAB415", hashtag_id: 1, apptype_id: 3, tag: { id: 1, name: "NodeJs", hashtag_group_id: 1 } }] }, { result_id: "AAD668", emp_id: 2, hashtag: [{ result_id: "AAD668", hashtag_id: 1, apptype_id: 3, tag: { id: 1, name: "NodeJs", hashtag_group_id: 1 } }] }, { result_id: "AAG239", emp_id: 1, hashtag: [{ result_id: "AAG239", hashtag_id: 4, apptype_id: 3, tag: null }] }, { result_id: "AAH740", emp_id: 1, hashtag: [{ result_id: "AAH740", hashtag_id: 2, apptype_id: 3, tag: null }] }, { result_id: "AAK119", emp_id: 2, hashtag: [{ result_id: "AAK119", hashtag_id: 1, apptype_id: 4, tag: { id: 1, name: "NodeJs", hashtag_group_id: 1 } }] }, { result_id: "AAK298", emp_id: 1, hashtag: [{ result_id: "AAK298", hashtag_id: 2, apptype_id: 3, tag: null }] }],
    result = data
        .flatMap(({ emp_id, hashtag }) => hashtag.map(({ apptype_id }) => ({ emp_id, apptype_id })))
        .filter((s => ({ emp_id, apptype_id }) => {
            const key = [emp_id, apptype_id].join('|');
            if (!s.has(key)) return s.add(key);
        })(new Set));

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

Solution 4:[4]

There is no structure comparison in JS, objects are compared by their "addresses in memory", you have to compare primitive values ([].indexOf(t) compares items of array with t).

console.log({text: 'hey'} !== {text: 'hey'})

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 scottmcgowan
Solution 3 Nina Scholz
Solution 4 random322