skip to Main Content

Using plain JavaScript or lodash, what’s the easiest way to transform an array of objects into a single object, while concatenating any array values?

I can achieve it on a single property using _.flatMap(before, "nodes") but not sure how to include all properties.

For example:

const before = [
  {
    nodes: [
      { "id": "1" },
      { "id": "2" }
    ],
    links: [
      { "source": "1", "target": "2" }
    ],
  },
  {
    nodes: [
        { "id": "3" },
        { "id": "4" },
        { "id": "5" },
        { "id": "6" }
    ],
    links: [
      { "source": "3", "target": "4" },
      { "source": "5", "target": "6" }
    ],
  }
];

const after = {
  nodes: [
    { "id": "1" },
    { "id": "2" },
    { "id": "3" },
    { "id": "4" },
    { "id": "5" },
    { "id": "6" }
  ],
  links: [
    { "source": "1", "target": "2" },
    { "source": "3", "target": "4" },
    { "source": "5", "target": "6" }
  ],
};

5

Answers


  1. You can achieve this using vanilla js using reduce and Object.entries as:

    const before = [
        {
            nodes: [
                { "id": "1" },
                { "id": "2" }
            ],
            links: [
                { "source": "1", "target": "2" }
            ],
        },
        {
            nodes: [
                { "id": "3" },
                { "id": "4" },
                { "id": "5" },
                { "id": "6" }
            ],
            links: [
                { "source": "3", "target": "4" },
                { "source": "5", "target": "6" }
            ],
        }
    ];
    
    const result = before.reduce((acc, curr) => {
        Object.entries(curr).forEach(([key, value]) => {
            acc[key] = [ ...(acc[key] ?? []), ...value];
        })
        return acc;
    }, {});
    
    console.log(result);
    Login or Signup to reply.
  2. Since you want to merge array into one, you should use reduce instead of map. Following should work

    after = before.reduce((prevResult, element) => {
        var newResult = {}
        Object.keys(element).forEach((key) => {
            newResult[key] = prevResult[key].concat(element[key])
        })
        return newResult
    })
    

    reduce will work with each element in iterative manner from left to right.

    Hope this helps

    Login or Signup to reply.
  3. One possible solution using lodash:

    const after = _.reduce(before, (acc, curr) => {
      _.forOwn(curr, (value, key) => {
        acc[key] = _.concat(acc[key] || [], value);
      });
      
      return acc;
    }, {});
    

    The result is a new object that contains these combined arrays.

    Login or Signup to reply.
  4. const before = [
      {
        nodes: [
          { "id": "1" },
          { "id": "2" }
        ],
        links: [
          { "source": "1", "target": "2" }
        ],
      },
      {
        nodes: [
            { "id": "3" },
            { "id": "4" },
            { "id": "5" },
            { "id": "6" }
        ],
        links: [
          { "source": "3", "target": "4" },
          { "source": "5", "target": "6" }
        ],
      }
    ];
    

    Following below code:

    const flatData = (data) => {
        const result = { nodes : [], links: [] };
    
        for (let i = 0; i < data.length; i++) {
            const {nodes, links} = data[i]; // nodes and links
    
            // nodes
            for (let i = 0; i < nodes.length; i++) {
                result.nodes = [...result.nodes, nodes[i]];
            }
    
            // links
            for (let i = 0; i < links.length; i++) {
                result.links = [...result.links, nodes[i]];
            }
        }
    
        return result;
    }
    
    Login or Signup to reply.
  5. You can use Array.reduce() to achieve this efficiently.

    Please find the following code:

    const before = [{
        nodes: [{
            "id": "1"
          },
          {
            "id": "2"
          }
        ],
        links: [{
          "source": "1",
          "target": "2"
        }],
      },
      {
        nodes: [{
            "id": "3"
          },
          {
            "id": "4"
          },
          {
            "id": "5"
          },
          {
            "id": "6"
          }
        ],
        links: [{
            "source": "3",
            "target": "4"
          },
          {
            "source": "5",
            "target": "6"
          }
        ],
      }
    ];
    
    const after = before.reduce((acc, curr) => {
        Object.keys(curr).forEach(key => {
            acc[key] = [...acc[key] , ...curr[key]]
        })
        return acc;
    })
    console.log("After is ===>>", after);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search