Milan
Milan

Reputation: 811

Merge two array of objects using lodash

I have two arrays of objects called movies and movieDetails:

const movies = [{
        movieID: 0,
        movieDetailsID: 9,
        movieName: "Dragonball Z",
        cost: 10
    },
    {
        movieID: 1,
        movieDetailsID: 10,
        movieName: "Spider Man",
        cost: 15
    },
    {
        movieID: 2,
        movieDetailsID: 11,
        movieName: "John Wick",
        cost: 20
    }
];

const movieDetails = [{
        movieDetailsID: 10,
        actor: "John Doe",
        fee: 100
    },
    {
        movieDetailsID: 10,
        actor: "Harry Styles",
        fee: 120
    },
    {
        movieDetailsID: 11,
        actor: "John Bane",
        fee: 200
    }
];
  1. I would like to some how merge these two array of objects and add details only if there is a matching movieDetailsID. I was thinking of using low dash for this?
  2. I would like to choose each objects (column names) I want to see from movies and movies details in my output i.e, for movies: movie name and cost. and movie details: actor and cost.

Expected Output:

 {
    movieID: 0,
    movieDetailsID: 9,
    movieName: "Dragonball Z",
    cost: 10
}, {
    movieID: 1,
    movieDetailsID: 10,
    movieName: "Spider Man",
    cost: 15,
    details: [{
            movieDetailsID: 10,
            actor: "John Doe",
            fee: 100
        },
        {
            movieDetailsID: 10,
            actor: "Harry Styles",
            fee: 120
        }
    ]
}, {
    movieID: 2,
    movieDetailsID: 11,
    movieName: "John Wick",
    cost: 20,
    details: [{
        movieDetailsID: 11,
        actor: "John Bane",
        fee: 200
    }]
}

What I have tried . However this seems to merge it in and doesnt create a seperate ovject details to add in those matching movie details ids.

var mergedList = _.map(movies, function(item){
        return _.extend(item, _.findWhere(movieDetailsID, { movieDetailsID: item.movieDetailsID }));
      });

Upvotes: 0

Views: 220

Answers (2)

NetSkylz
NetSkylz

Reputation: 414

If I understood everything, here's a solution in pure JS:

const movies = [
  {
    movieID: 0,
    movieDetailsID: 9,
    movieName: "Dragonball Z",
    cost: 10
  },
  {
    movieID: 1,
    movieDetailsID: 10,
    movieName: "Spider Man",
    cost: 15
  },
  {
    movieID: 2,
    movieDetailsID: 11,
    movieName: "John Wick",
    cost: 20
  }
];

const movieDetails = [
  {
    movieDetailsID: 10,
    actor: "John Doe",
    fee: 100
  },
  {
    movieDetailsID: 10,
    actor: "Harry Styles",
    fee: 120
  },
  {
    movieDetailsID: 11,
    actor: "John Bane",
    fee: 200
  }
];

const result = movies.map(movie => {
  const details = movieDetails.filter(md => md.movieDetailsID === movie.movieDetailsID);

  const { movieID, movieDetailsID, ...movieKeys } = movie;
  
  const filteredMovie = { ...movieKeys };
  
  if (details.length) {
    const filteredDetails = details.map(({
      movieDetailsID,
      ...keys
    }) => keys);

    return ({
        ...filteredMovie,
        details: filteredDetails,
    });
  }

  return filteredMovie;
});

console.log(result);

Upvotes: 0

Igor Loskutov
Igor Loskutov

Reputation: 2344

There you are, lodash solution, extremely simple

import groupBy from "lodash/groupBy";
import reduce from "lodash/reduce";

const result = reduce(movies, ([movieDetailsIndex, res], movie) => [
  movieDetailsIndex,
  [...res, {...movie, ...(movieDetailsIndex[movie.movieDetailsID] ?
    {details: movieDetailsIndex[movie.movieDetailsID]} : {}
  )}]
], [groupBy(movieDetails, "movieDetailsID"), []])[1];

Upvotes: 1

Related Questions