Leo Messi
Leo Messi

Reputation: 6166

Return only unique objects from an array in Javascript

Having the following array:

const arr = [{ id: 'A', version: 0, name: 'first' },
             { id: 'A', version: 1, name: 'first' },
             { id: 'B', version: 0, name: 'second' },
             { id: 'A', version: 2, name: 'first' },
             { id: 'B', version: 1, name: 'second' }];

I need to use this as input for two drop-downs.

For the first drop-down it should show in the list only two values, A and B.

For doing that:

const firstDropdownOptions = [...new Set(arr.map((el) => el.id))];

Unfortunately, this returns ['A', 'B'] which doesn't contain any information about the other properties.

It would be more useful to be like:

[{ id: 'A', version: '0', name: 'first' }, { id: 'B', version: '0', name: 'second' }]

Any ideas on how to make it return the above array?

Upvotes: 2

Views: 84

Answers (3)

Rohìt Jíndal
Rohìt Jíndal

Reputation: 27192

Observation : As you are only returning id in array.map() method. Hence, it is giving you only unique Id's [A, B] in a new array. To get all the other properties you have to fetch via condition to check if version === 0.

Working Demo :

const arr = [{ id: 'A', version: 0, name: 'first' },
             { id: 'A', version: 1, name: 'first' },
             { id: 'B', version: 0, name: 'second' },
             { id: 'A', version: 2, name: 'first' },
             { id: 'B', version: 1, name: 'second' }];
             
const firstDropdownData = arr.filter((obj) => obj.version === 0);

console.log(firstDropdownData);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386560

You could group by id and set all options for the second select by the selection of the first.

const
    setOptions = id => groups[id].forEach(o => {
        const option = document.createElement('option');
        option.value = o.version;
        option.innerHTML = o.version;
        second.appendChild(option);
    });

    data = [{ id: 'A', version: 0, name: 'first' }, { id: 'A', version: 1, name: 'first' }, { id: 'B', version: 0, name: 'second' }, { id: 'A', version: 2, name: 'first' }, { id: 'B', version: 1, name: 'second' }],
    first = document.createElement('select'),
    second = document.createElement('select'),
    groups = data.reduce((r, o) => ((r[o.id] ??= []).push(o), r), {});

document.body.appendChild(first);
document.body.appendChild(document.createTextNode(' '));
document.body.appendChild(second);

Object.keys(groups).forEach(k => {
    const option = document.createElement('option');
    option.value = k;
    option.innerHTML = k;
    first.appendChild(option);
});

setOptions('A');

first.addEventListener('change', function (event) {
    let i = second.options.length;
    while (i--) second.remove(i);
    setOptions(first.value);
});

Upvotes: 1

Leo Messi
Leo Messi

Reputation: 6166

I have found a short solution to this problem:

const result = arr.filter((value, index, self) => { 
    return self.findIndex(v => v.id === value.id) === index
});

Upvotes: 1

Related Questions