1

I have an array with objects and I need to remove duplicates based on the data-itemid prop.

This is my code:

const ListItemsUnique = []
ListItems.map(item => {
  if (ListItemsUnique.indexOf(item.props['data-itemid']) === -1) {
    ListItemsUnique.push(item)
  }
});

It returns exactly the same array as before, what am I doing wrong?

6
  • show the actual ListItemsUnique contents Commented Apr 6, 2017 at 11:51
  • it contains exactly the same objects as the ListItems array, if I push item.props['data-itemid'] into the ListItemsUnique it works correctly but obviously only the id's are in the array, I need the objects to be there Commented Apr 6, 2017 at 11:54
  • Have you tried filter instead, and then returning an object when found! Commented Apr 6, 2017 at 11:59
  • @funcoding how would the code look like, please? Commented Apr 6, 2017 at 12:10
  • Can you show a sample of ListItems contents? Commented Apr 6, 2017 at 12:15

3 Answers 3

2

if you are using ES6, Try this,

const ListItemsUnique = [...new Set(ListItems.map(item => item.props['data-itemid']))];

EDIT 1:

let data = [
  {
    name: 'John',
    "data-itemid": 2
  },
  {
    name: 'Doe',
    "data-itemid": 1
  },
  {
    name: 'James',
    "data-itemid": 1
  },
  {
    name: 'Clerk',
    "data-itemid": 2
  }
];

// Use Map (ES6) to retain only unique elements
let map = new Map();
for (element of data) {
  map.set(element["data-itemid"], element);
}


var filteredData = [];
map.forEach( (value) => {
  filteredData.push(value);
});

console.log(filteredData,"filteredData");

DEMO: https://codepen.io/vedp/pen/RpmVvx?editors=0011

Sign up to request clarification or add additional context in comments.

3 Comments

it returns an array with those IDs only whether I need objects instead
This only returns the unique data-itemid values, not the whole item. Also, you are mapping the wrong array. :)
@Ved, nice. Have an upvote. But you should probably ping the OP also ;)
1

The easiest and cleanest way would be to use a temporary set to store which items you have previously returned to your array, while you're mapping through it. Like so:

let tempSet = new Set();
const ListItemsUnique = ListItems.filter(item => {
  if(!tempSet.has(item.props['data-itemid'])) {
      tempSet.add(item.props['data-itemid']);
    return item;
  }
});

then do your mapping as usual.


Demo

let ListItems = [
  {name: "A", props: {"data-itemid": 1}},
  {name: "B", props: {"data-itemid": 1}},
  {name: "C", props: {"data-itemid": 2}},
  {name: "D", props: {"data-itemid": 3}},
  {name: "E", props: {"data-itemid": 3}},
];  //mock data

let tempSet = new Set();
const ListItemsUnique = ListItems.filter(item => {
  if(!tempSet.has(item.props['data-itemid'])) {
    tempSet.add(item.props['data-itemid']);
    return item;
  }
})

console.log(ListItemsUnique.map(item => item.name));  //Items "B" and "E" are skipped


By the way, Set is great for when dealing with, or wanting to achieve, a unique collection of data. Have a read on the MDN for more info on Set.

Here's a snippet from the docs:

Set objects are collections of values. You can iterate through the elements of a set in insertion order. A value in the Set may only occur once; it is unique in the Set's collection.

Comments

1

you can also use immutable js or JSON.stringify (depending on how deep ur objects are or how deep you want to compare ;) )

  1. use immutablejs - fromJS + compare
  2. use JSON.stringify

Example for JSON.stringify

const ListItems = [{a: 'a'}, {a: 'b'}, {a: 'a'}];

let ListItemsUnique = [];
let stringList = [];

ListItems.forEach(item => {
    const itemString = JSON.stringify(item);
    if (stringList.indexOf(itemString) === -1) {
        ListItemsUnique.push(item);
    }
    stringList.push(itemString);
})

console.log(ListItemsUnique);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.