Narayanan S
Narayanan S

Reputation: 127

How to avoid duplicate objects from two arrays after filter using java script

i have two arrays ( busns and pc ) i want to check pc array -> pcid is match with busns array -> pcid after match i want to return pcname. final output is comming but i want to avoid duplicate. thanks in advance

please check my attempt in jsfiddle

const busns = [
{
 id:1,
 shopname:'New trend',
 pcid:1
},
{
 id:2,
 shopname:'Latest Beauty',
 pcid:2
},
{
 id:3,
 shopname:'Mens Style',
 pcid:1
},
{
 id:4,
 name:'Fabulook',
 pcid: 1
},
{
 id:4,
 name:'New cut',
 pcid: 2
}
]

const pc = [
       {
         pcid:1,
         pcname: 'collection1'
       },
       {
         pcid:2,
         pcname: 'collection2'
       },
       {
         pcid:3,
         pcname: 'collection3'
       },
       {
         pcid:4,
         pcname: 'collection4'
       }
    ]

My code :

busns.map(busns => {
  return pc.filter( p => {
     return busns.pcid == p.pcid
  }).map(data => {
     console.log(data.pcname)
  })
})

expected output while using console :

collection1

collection2

Upvotes: 0

Views: 59

Answers (2)

Rajesh
Rajesh

Reputation: 24925

As commented, you could use this:

var ids = busns.map(x=>x.pcid); pc.filter(x=> ids.includes(x.pcid))


Your code:

What you are doing is,

  • Looping on business array to get current PC id.
  • Then you use this ID to filter out from PC's list and then use map to get name.

Now the issue with your code is, since you are looping on busns array, you are essentially printing the name of PC for every id.

const busns = [{ id: 1, shopname: 'New trend', pcid: 1 }, { id: 2, shopname: 'Latest Beauty', pcid: 2 }, { id: 3, shopname: 'Mens Style', pcid: 1 }, { id: 4, name: 'Fabulook', pcid: 1 }, { id: 4, name: 'New cut', pcid: 2 } ]

const pc = [{ pcid: 1, pcname: 'collection1' }, { pcid: 2, pcname: 'collection2' }, { pcid: 3, pcname: 'collection3' }, { pcid: 4, pcname: 'collection4' } ]

busns.map(busns => {
  return pc.filter(p => {
    return busns.pcid == p.pcid
  }).map(data => {
    console.log(data.pcname)
  })
})


Solution from comment:

Instead of nested looping structure, what you can do is,

  • Create a list of pcids. This will help you know if pc is traded.
  • Loop over pc array. Trades can be many but product will be finite and less in number. Use this to get a filtered list of products that are in busns.
  • Now loop over this filtered array and retrieve names. This part was not covered in comment.

const busns = [{ id: 1, shopname: 'New trend', pcid: 1 }, { id: 2, shopname: 'Latest Beauty', pcid: 2 }, { id: 3, shopname: 'Mens Style', pcid: 1 }, { id: 4, name: 'Fabulook', pcid: 1 }, { id: 4, name: 'New cut', pcid: 2 } ]

const pc = [{ pcid: 1, pcname: 'collection1' }, { pcid: 2, pcname: 'collection2' }, { pcid: 3, pcname: 'collection3' }, { pcid: 4, pcname: 'collection4' } ]

var ids = busns.map(x=>x.pcid); 
var pcNames = pc
  .filter(x=> ids.includes(x.pcid))
  .map(x=> x.pcname);

console.log(pcNames)


Preferred solution:

One issue with above approaches is extra iterations and duplicate pcid in list. So instead of using functions like .map + .filter, we can use .reduce and create unique list. This will keep iterations minimum.

  • Create a hashMap with keys as pcid and value as true. This will create a unique id map.
  • Now loop over pc array and check if current id is present in this object ot not. If present, push name. If not, continue.

I would suggest you to use this approach as this should be more performant. Using .map + .filter + .indexOf can be expensive for huge arrays.

const busns = [{ id: 1, shopname: 'New trend', pcid: 1 }, { id: 2, shopname: 'Latest Beauty', pcid: 2 }, { id: 3, shopname: 'Mens Style', pcid: 1 }, { id: 4, name: 'Fabulook', pcid: 1 }, { id: 4, name: 'New cut', pcid: 2 } ]

const pc = [{ pcid: 1, pcname: 'collection1' }, { pcid: 2, pcname: 'collection2' }, { pcid: 3, pcname: 'collection3' }, { pcid: 4, pcname: 'collection4' } ]

var ids = busns.reduce((acc, cur) => acc[cur.pcid] = true && acc, {});

var pcNames = pc.reduce((acc, cur) => {
  if(ids[cur.pcid]) {
    acc.push(cur.pcname);
  }
  return acc;
}, [])

console.log(pcNames)

Upvotes: 1

Constantiner
Constantiner

Reputation: 14221

Something like this.

pc.filter(p => busns.map(busns => busns.pcid).includes(p.pcid)).forEach(data => console.log(data.pcname));

Upvotes: 0

Related Questions