Subee Na
Subee Na

Reputation: 55

how do filter duplicate object in a array using JavaScript and return with a flag?

i have a array of object from there i need to filter duplicate item based on two key on return with extra key on it

let word = [
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
];

in above sample i want to filter out duplicate based on start and end key also need to add a key called haveDuplicate if same object have duplicate it need to be true

let filterd = [
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    haveDuplicate: true,
    name: "alex",
  },
];


i tried lodash but i cannot able to add extra key below is what i tried

_.uniqBy(data, obj => obj.start && obj.end);

Upvotes: 0

Views: 144

Answers (5)

Doppio
Doppio

Reputation: 2188

Here's an idea, use _.groupBy, and we can read number of items in group to determine if it has duplicate.

let word = [
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
];

const grouped = _.groupBy(word, o => `${o.start}-${o.end}`);

const result = _.map(grouped, occurrences => {
  if (occurrences.length > 1) return { ...occurrences[0], haveDuplicate: true };
  return occurrences[0];
})

console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Upvotes: 0

charlietfl
charlietfl

Reputation: 171698

To use _.uniquBy() you will need a function to return a value from each element that can be used to compare with.

This won't solve how to add the haveDuplicate property but is intended to just show how to use that specific method

const concatStartEnd = (o) => `${o.start}|${o.end}`;

console.log(_.uniqBy(word, concatStartEnd))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
let word=[{start:1,end:4,name:"alex"},{start:5,end:8,name:"sam"},{start:1,end:4,name:"alex"},{start:85,end:114,name:"Abhishek"},{start:1,end:4,name:"alex"}];
</script>

Upvotes: 0

Rahul Sharma
Rahul Sharma

Reputation: 10111

You can use an array filter,

you can update the key depending on your use case.

const word = [
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
];

const map = {};
const res = word.filter((item) => {
  const key = item.start + "-" + item.end;
  if (!map[key]) {
    map[key] = true;
    return true;
  }
  return false;
});

console.log(res);

Upvotes: 0

zb22
zb22

Reputation: 3231

You can use Array.prototype.reduce() and check if the item exist with Array.prototype.find() for that like so:

let word = [
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
];

const filteredArr = word.reduce((acc, curr) => {
  const obj = acc.find(item => item.start === curr.start && item.end === curr.end);
  if(obj) {
    if(!obj.haveDuplicate) {
      obj.haveDuplicate = true;
    }
    return acc;
  }
  
  acc.push(curr);
  return acc;
}, []);

console.log(filteredArr);

Array.prototype.reduce()
Array.prototype.find()

Upvotes: 1

mapr
mapr

Reputation: 119

You can combine reduce and Object.values

Object.values(word.reduce( (a,x) => { if(a[x.start+'-'+x.end]) x = {...x, haveDuplicate: true}; return a[x.start+'-'+x.end]=x,a} ,  {} ))

Upvotes: 0

Related Questions