Bjarke Andersen Bjarke Andersen - 1 year ago 65
Javascript Question

Merging two arrays on id - map function - Javascript

I am trying to merge two arrays on an id (sourceID). But fail to do so. The first array is the one below:

eventsToBeInserted = [{sourceID: 1, name: "BettyNansen"}, {sourceID: 2, name: "kongenshave"}]


This is the second array:

images = [{sourceID: 1, images: "Bettynansen.jpg"}, {sourceID: 2, name: "kongenshave.jpg"}]


I am looking to get the following:

events = [{sourceID: 1, name: "BettyNansen", images: "Bettynansen.jpg"}, {sourceID: 2, name: "kongenshave", images: "kongenshave.jpg"}]


This is my code:



const eventsToBeInserted = [{
sourceID: 1,
name: "BettyNansen"
}, {
sourceID: 2,
name: "kongenshave"
}]

const images = [{
sourceID: 1,
images: "Bettynansen.jpg"
}, {
sourceID: 2,
name: "kongenshave.jpg"
}]

events: !!eventsToBeInserted ? eventsToBeInserted.sourceID.map(sourceID => {
const event = images.name.find(eventLookup => eventLookup.sourceID === sourceID);
return [eventsToBeInserted.name, images.name]
}) : []




Answer Source

Basically what you want is, for every element in eventsToBeInserted, find all images that belong to it in the images array.

Note: In your images array, the first element has a property images and the second one has a property name.

const images = [{
  sourceID: 1,
  images: "Bettynansen.jpg"
// ^
}, {
  sourceID: 2,
  name: "kongenshave.jpg"
// ^
}]

It seems logical that both should use name so that's what my examples bellow will assume. If those objects can use both images and name, then you should || the two properties in the preferred order of existence when retrieving the value.

const eventsToBeInserted=[{sourceID:1,name:"BettyNansen"},{sourceID:2,name:"kongenshave"}],images=[{sourceID:1,name:"Bettynansen.jpg"},{sourceID:2,name:"kongenshave.jpg"}];

console.log(
  eventsToBeInserted.map(
    event => Object.assign({}, event, {
      images: images
        .filter(img => img.sourceID === event.sourceID)
        .map(img => img.name)
    })
  )
)

If each object will always match to only 1 image, as per your example, you can use find instead of filter on the images array:

Note: If you'll only ever have one image, it would make more sense to name that property image instead of images.

const eventsToBeInserted=[{sourceID:1,name:"BettyNansen"},{sourceID:2,name:"kongenshave"}],images=[{sourceID:1,name:"Bettynansen.jpg"},{sourceID:2,name:"kongenshave.jpg"}];

console.log(
  eventsToBeInserted.map(
    event => Object.assign({}, event, {
      image: (
        images.find(img => img.sourceID === event.sourceID) || {}
      ).name
    })
  )
)

If this operation needs to happen many times, converting images to a hash of sourceID: imageName would be more efficient.

const eventsToBeInserted=[{sourceID:1,name:"BettyNansen"},{sourceID:2,name:"kongenshave"}],images=[{sourceID:1,name:"Bettynansen.jpg"},{sourceID:2,name:"kongenshave.jpg"}];

const imagesHash = images.reduce((hash, img) => {
  hash[img.sourceID] = img.name;
  return hash;
}, {});

console.log(
  eventsToBeInserted.map(
    event => Object.assign({}, event, {
      image: imagesHash[event.sourceID]
    })
  )
)

Finally, assuming your environment allows it, you could use object spread to simplify the syntax:

const eventsToBeInserted=[{sourceID:1,name:"BettyNansen"},{sourceID:2,name:"kongenshave"}],images=[{sourceID:1,name:"Bettynansen.jpg"},{sourceID:2,name:"kongenshave.jpg"}];

const imagesHash = images.reduce((hash, img) => {
  hash[img.sourceID] = img.name;
  return hash;
}, {});

console.log(
  eventsToBeInserted.map(
    event => ({
      ...event,
      image: imagesHash[event.sourceID]
    })
  )
)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download