1

I receive an array from an API which looks as follows:

results = [
  {name: 'Ana', country: 'US', language: 'EN'},
  {name: 'Paul', country: 'UK', language: 'EN'},
  {name: 'Luis', country: 'PH', language: 'SP'},
  {name: 'Tom', country: 'US', language: 'EN'}
];

From this I'd like to create an array that looks like this:

countries = [
  {filter: 'country', value: 'PH'},
  {filter: 'country', value: 'UK'},
  {filter: 'country', value: 'US'},
];

To this end, what I tried is:

countries = Array.from([...new Set(this.results.map(item => ({categoryOfFilter: 'country', value: item.country})))]);

Because I was told to use set. This does create an array as specified above, but it contains duplicates. Like so:

countries = [
  {filter: 'country', value: 'US'},
  {filter: 'country', value: 'UK'},
  {filter: 'country', value: 'PH'},
  {filter: 'country', value: 'US'},
];

Do you guys have any idea? The truth is that I was never any good with js in the first place so I'm waaay beyond stretching here.

2 Answers 2

3

The Set object lets you store unique values of any type, whether primitive values or object references.

Sets don't work like that with objects. The items are all different, as they have different object references, even if their attributes all have equal values.

It will work like that (split it into two line to keep it a bit readable)

results = [
  {name: 'Ana', country: 'US', language: 'EN'},
  {name: 'Paul', country: 'UK', language: 'EN'},
  {name: 'Luis', country: 'PH', language: 'SP'},
  {name: 'Tom', country: 'US', language: 'EN'}
];

// create a set with all country codes. Set works fine with strings
const countryCodes = new Set(results.map(item => item.country));

// spread the set values into a new array and map that to the target objects
const countries = [...countryCodes].map(value => {return {filter: 'country', value}});

console.log(countries);
Sign up to request clarification or add additional context in comments.

Comments

2

See this codepen: https://codepen.io/kyletanders/pen/NWqpWVX?editors=0012

something like this:


    const data = [
      {name: 'Ana', country: 'US', language: 'EN'},
      {name: 'Paul', country: 'UK', language: 'EN'},
      {name: 'Luis', country: 'PH', language: 'SP'},
      {name: 'Tom', country: 'US', language: 'EN'}
    ];

    let unique = [...new Set(data.map(item => item.country))].map(x => {return {filter: 'Country', value: x}});
    console.log(unique);

3 Comments

Thanks Kyle, it worked beautifully. But may I ask why is the return necessary in the second map? Sorry to ask such a silly sounding question, but I'm really a newbie here and want to understand fully, not only make it work...
The answer below has a cleaner version that is easier to read. But essentially what we're doing here is getting a distinct version of the countries and then rebuilding the object that you want , with the filter and value properties. The return is actually not entirely necessary you could do it like: x => ({filter: 'Country', value: x}) like you had it before. Just different syntaxes. Since I used curly braces I was declaring an inline function which then needed to return the result.
To add to that... with the curly braces you can do multi-line statements. Which didn't end up being necessary here. But that is the main reason I would use the inline function is if I wanted to do a complicated multi-line mapping.

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.