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?
CodePudding user response:
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
});
CodePudding user response:
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);
});