2

So I have an Object that contains multiple arrays

x = {
    c: ['Full_Name', 'Last_Name', 'Email', 'Organizations', 'MISC', 'UNIQUEID']
    small: ['Title', 'Organizations', 'URL', 'UNIQUEID']
    .
    .
    .}

What is the best and the fastest way to find all the similar elements from all these arrays?

So for example in this case the answer will be ['Organization', 'UNIQUEID']

3
  • check stackoverflow for array intersection: stackoverflow.com/questions/1885557/… Commented Aug 3, 2022 at 21:02
  • What should happen if one of the arrays in x is []? Should that always produce an empty array as the result? Or should the result array still contain some values since, for example, "UNIQUEID" is in more than one (but not all) arrays in x? Commented Aug 3, 2022 at 21:16
  • 1
    Then it should give an empty array as a result. Commented Aug 3, 2022 at 21:20

2 Answers 2

3

a possible approach using reduce and Set. for the accumulator I'm initializing it with the first array (x.c). Doesn't matter which one since in the end we are taking intersection anyway. Inside the reduce I'm intersecting the accumulator with the current iteration array

const x = {
  c: ['Full_Name', 'Last_Name', 'Email', 'Organizations', 'MISC', 'UNIQUEID'],
  small: ['Title', 'Organizations', 'URL', 'UNIQUEID'],
  big: ['abc', 'Organizations', 'def', 'UNIQUEID']
}


const res = Object.values(x).reduce((acc, curr) => {
  return new Set(curr.filter(i => acc.has(i)))
}, new Set(x.c))

console.log([...res])

almost similar with a for loop except I'm skipping first element in loop

const x = {
  c: ['Full_Name', 'Last_Name', 'Email', 'Organizations', 'MISC', 'UNIQUEID'],
  small: ['Title', 'Organizations', 'URL', 'UNIQUEID'],
  big: ['abc', 'Organizations', 'def', 'UNIQUEID']
}

const values = Object.values(x)
let acc = new Set(values[0])
for (let i = 1; i < values.length; i++) {
  acc = new Set(values[i].filter(j => acc.has(j)))
}

console.log([...acc])

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

1 Comment

isnt it intended im not sure
1

You're looking for a Set intersection -

function intersection2(a, b) {
  if (a.size > b.size)
    return intersection2(b, a)
  const r = new Set
  for (const v of a)
    if (b.has(v))
      r.add(v)
  return r
}

You can compute the intersection of many sets by combining reduce and intersection2 -

function intersection(s, ...sets) {
  return sets.reduce(intersection2, s)
}

To use it with your code, get all values of x using Object.values and map over them to create an array of sets. Finally call intersection with all of the sets -

const x = {
  c: ['Full_Name', 'Last_Name', 'Email', 'Organizations', 'MISC', 'UNIQUEID'],
  small: ['Title', 'Organizations', 'URL', 'UNIQUEID'],
  big: ['abc', 'Organizations', 'def', 'UNIQUEID']
}

const result =
  intersection(...Object.values(x).map(v => new Set(v)))

console.log(result)
Set [ "Organizations", "UNIQUEID" ]

If you want the result as an array, you can convert it using Array.from -

console.log(Array.from(result))
[ "Organizations", "UNIQUEID" ]

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.