2

So say i have a dataset like this.

posts = [
{
  title: 'title1',
  category: 'cat1',
  tags: ['tag1', 'tag2', 'tag3', 'tag4']
},
{
  title: 'title2',
  category: 'cat1',
  tags: ['tag1', 'tag2', 'tag5']
}];

I'd like to get a list of the unique tags in all the posts like so:

['tag1', 'tag2', 'tag3', 'tag4', 'tag5']

I found this response that covers how to this for a single prop:

const categories = [...new Set(posts.map(post => post.category))];

But I can't seem to get the syntax for tags. Something like this (predictably), adds the arrays instead of the destructed values:

const tags = [...new Set(posts.map(post => post.tags))];

Obviously I can loop through each post and the grab them that way, but I'm sure there's a more elegant way using ES6 that I just haven't figured out yet. Any thoughts here?

Paul DeVito
  • 1,542
  • 3
  • 15
  • 38

1 Answers1

2

Use Array.flatMap() to get a flattened array of tags to create the Set:

const posts = [{"title":"title1","category":"cat1","tags":["tag1","tag2","tag3","tag4"]},{"title":"title2","category":"cat1","tags":["tag1","tag2","tag5"]}];

const result = [...new Set(posts.flatMap(p => p.tags))];

console.log(result);

If Array.flatMap() is not supported, you can spread the array of arrays created by your Array.map() into Array.concat() to flatten it:

const posts = [{"title":"title1","category":"cat1","tags":["tag1","tag2","tag3","tag4"]},{"title":"title2","category":"cat1","tags":["tag1","tag2","tag5"]}];

const result = [...new Set([].concat(...posts.map(p => p.tags)))];

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • Perfect! Thanks, `flatMap` worked. Every time I think I am getting a grasp on all the js and es6 tricks, I come across another one I didn't know about! cheers – Paul DeVito Apr 16 '21 at 03:16
  • 1
    You're welcome. `Array.flatMap()` is not actually part of ES6, but a later version, and that's why I added a fallback. – Ori Drori Apr 16 '21 at 03:18