Search code examples
javascriptnode.jslodash

How to extend and merge a list of objects with another list using lodash


hopefully there is someone here with enough experience to guide me through this particular issue I've found. So I am working with this peculiar API that returns an object akin to the following:

const api_response = {
  environment_list: ["dev", "non-prod"],
  member_list: [
    { id: "abc-456", name: "Homer", "last-name": "Simpson", role: "admin" },
  ],
};

The goal I'm trying to achieve is to create a new list that contains the user id, name, role, and environment based on the environment list above so it should look like this:

[
   { id: 'abc-456', name: 'Homer', role: 'admin', environment: 'dev' },
   { id: 'abc-456', name: 'Homer', role: 'admin', environment: 'non-prod' }
]

Now what I have done is the following:

I created a variable to isolate each value that will be be merged:

const userList = _.map(api_response.member_list, (data) => ({
  id: data.id,
  name: data.name,
  role: data.role,
}));

const environmentList = _.map(api_response.environment_list, (data) => ({
  environment: data,
}));

Then these two were merged as one list of objects:

const extendAndMergeList = _.map(environmentList, (data) =>
  _.map(userList, (items) => ({ ...items, environment: data.environment }))
);

And the output is close enough to my final product which is:

[
  [
    { id: 'abc-456', name: 'Homer', role: 'admin', environment: 'dev' }
  ],
  [
    {
      id: 'abc-456',
      name: 'Homer',
      role: 'admin',
      environment: 'non-prod'
    }
  ]
]

I'm probably doing something silly but would love to have some guidance in how to trim this from a list of lists to a list of objects.

another look at all the steps I took:

const _ = require("lodash");

const api_response = {
  environment_list: ["dev", "non-prod"],
  member_list: [
    { id: "abc-456", name: "Homer", "last-name": "Simpson", role: "admin" },
  ],
};

const userList = _.map(api_response.member_list, (data) => ({
  id: data.id,
  name: data.name,
  role: data.role,
}));

const environmentList = _.map(api_response.environment_list, (data) => ({
  environment: data,
}));

const extendAndMergeList = _.map(environmentList, (data) =>
  _.map(userList, (items) => ({ ...items, environment: data.environment }))
);

Thank you again for any helpful response!


Solution

  • The easy way is to use the _.flatten method of lodash to achieve this:

    const _ = require('lodash');
    
    const data = _.map(api_response.environment_list, e => 
        _.map(api_response.member_list, m => ({
            id: m.id, 
            name: m.name, 
            role: m.role, 
            environment: e
        })
    ); // This step achieves the exact same thing that you have achieved up until now in your question.
    
    const flattenedData = _.flatten(data); // This is the method you need to make the array "flat".
    
    console.log(flattenedData);
    

    You could also attempt to do this without using lodash in this, a bit more efficient, way:

    const output = [];
    for (const e of api_response.environment_list) {
        for (const m of api_response.member_list) {
            const obj = {
                id: m.id, 
                name: m.name, 
                role: m.role, 
                environment: e
            };
            output.push(obj);
        }
    }