0

I have an object that looks like this:

const posts = [
               { id: 0, user: { id: 5564, name: 'john'} },
               { id: 1, user: { id: 5564, name: 'john'} },
               { id: 2, user: { id: 5560, name: 'jane'} }
              ]

I need an array of the unique user hashes like this:

[
 { id: 5564, name: 'john'},
 { id: 5560, name: 'jane'}
]

I'm able to retrieve all the users attributes from the posts array by doing:

const postUsers = posts.map(post => post.user)

which returns:

[
 { id: 5564, name: 'john'},
 { id: 5564, name: 'john'},
 { id: 5560, name: 'jane'}
]

where user john is listed twice

I've been able to get my desired result by doing:

const unique = {};
const uniqueUsers = [];
for(var i in postUsers){
  if(typeof(unique[postUsers[i].id]) == "undefined"){
    uniqueUsers.push(postUsers[i]);
  }
  unique[postUsers[i].id] = 0;
};
uniqueUsers

but there must be a cleaner way. I've also been able to return the unique ids of all users by doing:

var ids = posts.map(post => post.user.id)

var uniqueIds = Array.from(new Set(ids)).sort(); which returns [5564, 5560]

not sure if that helps. this article helped me a little https://medium.com/tomincode/removing-array-duplicates-in-es6-551721c7e53f

3
  • Is just the id sufficient to check for uniqueness or do you need to consider both id and name? Commented Jul 1, 2019 at 21:05
  • 2
    These are called objects in JavaScript, not hashes (that's the Perl term). Commented Jul 1, 2019 at 21:06
  • 1
    Object.values(posts.reduce((r, {user}) => r[user.id] ? r : (r[user.id] = user, r), {})) Commented Jul 1, 2019 at 21:07

4 Answers 4

0

You could take a Map and get only the unique users.

const
    posts = [{ id: 0, user: { id: 5564, name: 'john'} }, { id: 1, user: { id: 5564, name: 'john'} }, { id: 2, user: { id: 5560, name: 'jane'} }],
    unique = Array.from(posts.reduce((m, { user }) => m.set(user.id, user), new Map).values());

console.log(unique);

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

Comments

0

If you don't mind using lodash you can do something like

const users = _map.(posts, 'user') // To get the list of users
_.uniqBy(users, 'id') // to get the uniq ones

Comments

0

Put the objects directly in uniqueUsers, then use Object.values() at the end to convert the object to an array.

const posts = [
   { id: 0, user: { id: 5564, name: 'john'} },
   { id: 1, user: { id: 5564, name: 'john'} },
   { id: 2, user: { id: 5560, name: 'jane'} }
];
let uniqueUsers = {};
posts.forEach(({user}) => uniqueUsers[user.id] = user);
uniqueUsers = Object.values(uniqueUsers);
console.log(uniqueUsers);

Comments

0

Use reduce to reduce the array by checking if the value is already in the array. If it is already in the array, return the current state of the array, otherwise add the item to the array.

const posts = [
  { id: 0, user: { id: 5564, name: 'john'} },
  { id: 1, user: { id: 5564, name: 'john'} },
  { id: 2, user: { id: 5560, name: 'jane'} }
]

const r = posts.map(i => i.user).reduce((acc, itm) => {
  return !acc.find(i => i.id == itm.id) && acc.concat(itm) || acc
}, [])

console.log(r)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.