0

What I want to do is basically join the information from two arrays via userId. Until then, this solution that I made works only when there is little data, if they are very large arrays, this huge amount of filter is very impractical. Can anyone think of a more efficient solution?

PS: I'm using > 0 ? because sometimes one of the properties is empty.

const data01 = [
      { userId: 0, motorcycles: 'motorcycle01', cars: 'car01' },
      { userId: 1, motorcycles: 'motorcycle02', cars: 'car02' },
      { userId: 2, cars: 'car03' },
      { userId: 3, motorcycles: 'motorcycle04' },
    ]


    items.forEach(
      a =>
      (
        a.motorcylces = data01.filter(b => b.userId === a.userId).length > 0 ? data01.filter(b => b.userId === a.userId)[0].motorcylces : null,
        a.cars = data01.filter(b => b.userId === a.userId).length > 0 ? data01.filter(b => b.userId === a.userId)[0].cars : null
      )
    );

    console.log(items)

Expected Output:

[
    {
       ...
       motorcycles: 'motorcycle01',
       cars: 'cars01'
    },
    {
       ...
       motorcycles: 'motorcycle01',
       cars: 'cars01'
    }
]
9
  • Can you please add a sample output? Also which one is the 2nd array ? Commented Jul 8, 2021 at 16:49
  • Why are you using the comma operator here? Just use an ordinary function body with two assignments. Commented Jul 8, 2021 at 16:50
  • @Dharmaraj done! Commented Jul 8, 2021 at 16:53
  • @Barmar I believe the code gets cleaner Commented Jul 8, 2021 at 16:55
  • 1
    BTW, you misspelled motorcycles Commented Jul 8, 2021 at 16:57

2 Answers 2

2

You can speed up the process by creating a Map of data01, keyed by userId.

And with Object.assign you can copy the properties from a match. This will not create the property if it doesn't exist in the source, so there will be no null assignments (unless the source has an explicit null):

let map = new Map(data01.map(o => [o.userId, o]));
items.forEach(a => Object.assign(a, map.get(a.userId)));

If you are only interested in a selection of properties, then create objects that only have those properties:

let map = new Map(data01.map(o => 
    [o.userId, { cars: o.cars, motorcycles: o.motorcycles }]
));
items.forEach(a => Object.assign(a, map.get(a.userId)));

This second solution will always create the specific properties, also when they didn't exist yet. In that case their values will be undefined.

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

3 Comments

In this case I want to keep the properties of the "items" array and add the properties "motorcycles" and "cars"
OK, so then go for the second variant in my answer. But also the first keeps the properties of the items array. It just doesn't always add the "motorcycles" and "cars" properties -- when they don't exist in data01.
Even with this optimization it takes more than 5 seconds to merge the data : / But your answer was good.
1

If your arrays are arrays of objects, and you need to consolidate 2+ arrays based on some property in the object, seems like the best thing to do would be to make an intermediate map that has its keys as the userIDs, and then just code something that will non-destructively update the map as you iterate through the arrays.

const data01 = [
      { userId: 0, motocycles: 'motocycle01', cars: 'car01' },
      { userId: 1, motocycles: 'motocycle02', cars: 'car02' },
      { userId: 2, cars: 'car03' },
      { userId: 3, motocycles: 'motocycle04' },
    ]

const data02 = [
      { userId: 0, dogs: 'doggy', cats: 'car01' },
      { userId: 1, dogs: 'doggo', cats: 'car02' },
      { userId: 2, dogs: 'sheperd' },
      { userId: 3, cats: 'kitty' },
    ]


function combineArrFromUserId(arr1,arr2){
  const idMap= new Map()
  data01.forEach(item=>checkAndAdd(item,idMap))
  data02.forEach(item=>checkAndAdd(item,idMap))
  return idMap.values()
}

function checkAndAdd(item,map){
  const current =  map.get(item.userId)
  if(current){
    map.set(item.userId,Object.assign(current,item))
  } else {
    map.set(item.userId, item)
  }
}

console.log(combineArrFromUserId(data01,data02))

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.