Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

223
Views
Finding intersection between 2 arrays of objects with dynamic keys

I have 2 arrays of objects with dynamic keys (i never know the name of the key); Example:

hierarchy1: [
  {
    level1: 'Shoes',
  }
]

hierarchy2: [
  {
    level1: 'Shoes',
    level2: 'Sneakers',
  },
]

I need to find intersection between hierarchy1 and hierarchy2. I can't use lodash _.intersectionBy because i dont know the name of the key i will get in hierarchy1.

I'd expect to get the result like this [{ level1: 'Shoes' }] Any ideas how to solve this issue?

Thanks a lot!

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

if you want to compare with every index then you can do something like this

const hierarchy1 = [{
  level1: 'Shoes',
  level3: "xyz"
}]

const hierarchy2 = [{
  level1: 'Shoes',
  level2: 'Sneakers',
}, {
  level3: "xyz"
}]

function intersection(arr1, arr2) {
  let final = []
  // loop over first array
  for (let i = 0; i < arr1.length; i++) {
    let element = arr1[i]
    let temp = {}
    
    // loop over all indexes of second array
    for (let data of arr2) {
      // check every key fro data to see if there's any intersection
      Object.keys(data).forEach(key => {
        if (data[key] === element[key] && key in element) {
          temp[key] = element[key]
        }
      })
    }
    // if we found any intersection push it in final array
    if (Object.keys(temp).length) {
      final.push(temp)
    }
  }
  return final
}

console.log(intersection(hierarchy1, hierarchy2))

an improvement to first approach is doing some pre-calculations, you can simply club all the values for a particular key and when looping over you can check if there's particular value present for the given key or not

const hierarchy1 = [{
  level1: 'Shoes',
  level3: "xyz"
},{level2: "abc"}]

const hierarchy2 = [{
  level1: 'Shoes',
  level2: 'Sneakers',
}, {
  level3: "xyz",
  level2: "abc"
}]

function intersection(arr1, arr2) {
  let final = []
  let map = {}
  for(let data of arr2){
    Object.keys(data).forEach(key => {
      map[key] = map[key] || new Set()
      map[key].add(data[key])
    })
  }
  // loop over first array
  for (let i = 0; i < arr1.length; i++) {
    let element = arr1[i]
    let temp = {}
    Object.keys(element).forEach(key => {
      if (key in map && map[key].has(element[key])) {
         temp[key] = element[key]
      }
    })
    // if we found any intersection push it in final array
    if (Object.keys(temp).length) {
      final.push(temp)
    }
  }
  return final
}

console.log(intersection(hierarchy1, hierarchy2))

If you just want to compare respective indexes or both array you can do something like this

const hierarchy1 = [{
  level1: 'Shoes',
}]

const hierarchy2 = [{
  level1: 'Shoes',
  level2: 'Sneakers',
},]

function intersection(arr1,arr2){
  let final = []
  for(let i=0; i<arr1.length; i++){
    let element = arr1[i]
    let temp = {}
    Object.keys(element).forEach(key => {
       if(key in arr2[i] && arr2[i][key] === element[key]){
         temp[key] = element[key]
       }
    })
    if(Object.keys(temp).length){
      final.push(temp)
    }
  }
  return final
}

console.log(intersection(hierarchy1,hierarchy2))

about 4 years ago · Juan Pablo Isaza Report

0

You can use _.intersectionWith() that accepts multiple arrays, and a comparator function to compare between two items. To find matching keys, we can use _.intersection() between the keys of the two objects, and then use Array.some() to find at least one key that have matching values in both objects.

const intersectionWithDynamicKeys = (arr1, arr2) => _.intersectionWith(
  arr1, arr2, (o1, o2) => 
    _.union(_.keys(o1), _.keys(o2))
     .some(key => o1[key] === o2[key])
)

// Finds [{ level1: 'Shoes' }]
console.log(intersectionWithDynamicKeys(
  [{ level1: 'Shoes' }],
  [{ level1: 'Shoes', level2: 'Sneakers' }]
))

// Finds [{ level1: 'Shoes' }] but doesn't find { level2: 'Sneakers' 
console.log(intersectionWithDynamicKeys(
  [{ level1: 'Shoes' }, { level2: 'Sneakers' }],
  [{ level1: 'Shoes', level2: 'Sneakers' }]
))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

The main caveat using _.intersectionWith() is that as soon as an item matches it's not used again. So if for example you have

const arr1 = [{ level1: 'Shoes' }, { level2: 'Sneakers' }],
const arr2 = [{ level1: 'Shoes', level2: 'Sneakers' }]

only the { level1: 'Shoes' } because { level1: 'Shoes', level2: 'Sneakers' } would not be used to compare with { level2: 'Sneakers' }, since a match was found.

If you want to find all objects with matching keys, you'll need to compare all objects in one array to all objects in the other. To do so, filter the 1st array. Use Array.some() to iterate the 2nd array. Get all unique keys (using a Set), and then try to find at least one key that has the same value in both objects.

Note: without the match once limit, multiple objects from the 1st array can be matched by a single object in the 2nd.

const getUniqueKeys = (o1, o2) => [...new Set([...Object.keys(o1), ...Object.keys(o2)])]

const intersectionWithDynamicKeys = (arr1, arr2) =>
  arr1.filter(o1 => 
    arr2.some(o2 => 
      getUniqueKeys(o1, o2)
      .some(key => o1[key] === o2[key])
    )
  )

// Finds [{ level1: 'Shoes' }, { level2: 'Sneakers' }]
console.log(intersectionWithDynamicKeys(
  [{ level1: 'Shoes' }, { level2: 'Sneakers' }],
  [{ level1: 'Shoes', level2: 'Sneakers' }]
))

// Finds [{ level1: 'Shoes' }, { level2: 'Sneakers' }, { level2: 'Sneakers' }]
console.log(intersectionWithDynamicKeys(
  [{ level1: 'Shoes' }, { level2: 'Sneakers' }, { level2: 'Sneakers' }],
  [{ level1: 'Shoes', level2: 'Sneakers' }]
))

about 4 years ago · Juan Pablo Isaza Report

0

You can use this to reshape it a tad.

var all = [...hierarchy1, ...hierarchy2].map(c=> Object.entries(c)).flat()
/*
[
  [ 'level1', 'Shoes' ],
  [ 'level1', 'Shoes' ],
  [ 'level2', 'Sneakers' ]
]
*/

Then put it into whatever format you want after that

all.reduce((a,[key,value])=>({
     ...a, 
    [key]: a[key]?a[key]+1:1
  }),{})

/*
{ level1: 2, level2: 1 }
*/
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!