2
\$\begingroup\$

I found a couple of similar questions, but they were mostly outdated. Here's the problem: create a flat array from the values in several arrays contained in several nested objects.

const data = [
  { id: 1, items: ['one', 'two', 'three'] },
  { id: 2, items: ['two', 'one', 'four'] },
]

Expected result const result = ['one', 'two', 'three', 'four']

My current solution:

function() {
  const result = []
  data.forEach(item => data.items.forEach(item => result.push(item)))

  return _.uniq(result)
}

lodash is allowed

Any suggestion is more than welcome

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Although at the time of writing, flatMap is not in every browser (according to MDN not in Edge and Samsung Internet);

data.flatMap(obj => obj.items).filter((e, i, ary) => ary.indexOf(e) == i)

Although, you could check the uniqueness from the result array in your code, and push only if not in there, to save one loop over the array.

Another option would be a reducer like

uniqItems = (acc, {items}) => acc.concat(items.filter(item => acc.indexOf(item) < 0))

to data.reduce(uniqItems, []).

\$\endgroup\$
1
\$\begingroup\$

Use a Set, it will store unique items for you.

You can convert the set to an array with [...set.values()];

Or as a set is iterateable there is no need to convert it to an array until needed if at all.

const data = [{items: ['one', 'two', 'three'] },{items: ['two', 'one', 'four'] }];

// Quickest solution
function getUniqueA(arr) {
    const unique = new Set();
    for (const {items} of arr) {
        for (const item of items) { unique.add(item) }
    }
    return [...unique.values()];
}

// Smallest solution
const getUniqueB = arr => [...(new Set(arr.map(i => i.items).flat())).values()];
    
// Returns the set
const getUniqueC = arr => new Set(arr.map(i => i.items).flat());
    
const resA = getUniqueA(data);
const resB = getUniqueB(data);
const resC = getUniqueC(data);

logArray("Result A: ", resA);
logArray("Result B: ", resB);
logArray("Result C: ", ...resC);

function logArray(t, ...a) { console.log(t + `[${a}]`) }

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.