2

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?

5
  • 1
    const firstDropdownOptions = arr.filter(({version}) => version === 0);. Commented Feb 17, 2022 at 17:36
  • 1
    Why should A return the object with version: '0' and not version: '1'? In fact, ['A', 'B'] may be any thing like: [{ id: 'A', version: '1', name: 'first' }, { id: 'B', version: '0', name: 'second' }] or [{ id: 'A', version: '2', name: 'first' }, { id: 'B', version: '0', name: 'second' }] or [{ id: 'A', version: '0', name: 'first' }, { id: 'B', version: '1', name: 'second' }] or ... Commented Feb 17, 2022 at 17:42
  • 1
    Yeah - but which object - there are 3 objects with A and 2 with B. So, what is the logic to choose which one of the objects for the letters? Commented Feb 17, 2022 at 17:45
  • @LeoMessi No, it works for your particular example only. Commented Feb 17, 2022 at 17:46
  • @Leo Messi I added an answer. I hope it helps as per the problem statement you have. Commented Feb 20, 2022 at 12:07

3 Answers 3

1

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);
});

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

Comments

1

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
});

Comments

0

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);

Comments

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.