2

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]
}) : []

1

1 Answer 1

4

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]
    })
  )
)

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

2 Comments

Thank you @nem035. Really appreciate the thorough and detailed explanation!
@BjarkeAndersen no problem, glad to help amigo :)

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.