Nazir
Nazir

Reputation: 414

How do I merge two Javascript Objects into one?

I Have two Array of Objects :

salesLabelData -

"salesData": [
{
  "id": "weekly",
  "chartData": {
    "dataSets": [
      {
        "borderColor": "#2E87A8",
        "backgroundColor": "#2E87A8",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "borderColor": "#951DAC",
        "backgroundColor": "#951DAC",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "borderColor": "#FA9610",
        "backgroundColor": "#FA9610",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      }
    ]
  }
},
{
  "id": "monthly",
  "chartData": {
    "dataSets": [
      {
        "id": "target-qty",
        "borderColor": "#2E87A8",
        "backgroundColor": "#2E87A8",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "net-sales",
        "borderColor": "#951DAC",
        "backgroundColor": "#951DAC",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "gap",
        "borderColor": "#FA9610",
        "backgroundColor": "#FA9610",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      }
    ]
  }
 }
]

salesAPIData :

"salesData": [
{
  "id": "weekly",
  "chartData": {
    "labels": [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "July",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec"
    ],
    "datasets": [
      {
        "id": "target-qty",
        "type": "bar",
        "label": "Target Qty",
        "data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]
      },
      {
        "id": "net-sales",
        "type": "bar",
        "label": "Net Sales Qty",
        "data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]
      },
      {
        "id": "gap",
        "type": "line",
        "label": "Gap",
        "data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]
      }
    ]
  }
},
{
  "id": "monthly",
  "chartData": {
    "labels": [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "July",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec"
    ],
    "datasets": [
      {
        "id": "target-qty",
        "type": "bar",
        "label": "Target Qty",
        "data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]
      },
      {
        "id": "net-sales",
        "type": "bar",
        "label": "Net Sales Qty",
        "data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]
      },
      {
        "id": "gap",
        "type": "line",
        "label": "Gap",
        "data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]
      }
    ]
  }
 }

]

I need to merge these, to eventually get this array (Basically the Datasets have to be merged into one) :

Expected Result -

"salesData": [
{
  "id": "weekly",
  "chartData": {
    "labels": [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "July",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec"
    ],
    "datasets": [
      {
        "id": "target-qty",
        "type": "bar",
        "label": "Target Qty",
        "data": [
          450,
          480,
          379,
          325,
          425,
          287,
          274,
          499,
          333,
          401,
          123,
          444
        ],
        "borderColor": "#2E87A8",
        "backgroundColor": "#2E87A8",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "net-sales",
        "type": "bar",
        "label": "Net Sales Qty",
        "data": [
          450,
          480,
          379,
          325,
          425,
          287,
          274,
          499,
          333,
          401,
          123,
          444
        ],
        "borderColor": "#951DAC",
        "backgroundColor": "#951DAC",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "gap",
        "type": "line",
        "label": "Gap",
        "data": [
          450,
          480,
          470,
          420,
          425,
          436,
          401,
          411,
          422,
          433,
          499,
          444
        ],
        "borderColor": "#FA9610",
        "backgroundColor": "#FA9610",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      }
    ]
  }
},
{
  "id": "monthly",
  "labelName": "TARGET",
  "chartData": {
    "labels": [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "July",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec"
    ],
    "datasets": [
      {
        "id": "target-qty",
        "type": "bar",
        "label": "Target Qty",
        "data": [
          950, 980, 379, 325, 925, 287, 279, 999, 333, 901, 123, 999
        ],
        "borderColor": "#2E87A8",
        "backgroundColor": "#2E87A8",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "net-sales",
        "type": "bar",
        "label": "Net Sales Qty",
        "data": [
          950, 980, 379, 325, 925, 287, 279, 999, 333, 901, 123, 999
        ],
        "borderColor": "#951DAC",
        "backgroundColor": "#951DAC",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      },
      {
        "id": "gap",
        "type": "line",
        "label": "Gap",
        "data": [
          950, 980, 379, 325, 925, 287, 279, 999, 333, 901, 123, 999
        ],
        "borderColor": "#FA9610",
        "backgroundColor": "#FA9610",
        "fill": "false",
        "pointRadius": "3",
        "pointHoverRadius": "4",
        "borderWidth": "2"
      }
    ]
  }
}
]

I have tried the following and other various permutations/combinations, checked out many answers on this site but none worked:

    if (salesLabelData?.salesData && salesAPIData?.salesData) {
      const array1 = salesLabelData.salesData;
      const array2 = salesAPIData.salesData;
      array1?.map((data, index) => {
        if (data.id === array2[index].id) {
          const labelData = {
            ...data,
            ...array2[index],
          };
          salesBarChartData.push(labelData);
        }
        return salesBarChartData;
      });
    }

I am missing something, not sure what and hence am not able to get the desired result, Any Help is sincerely appreciated.

Upvotes: 1

Views: 108

Answers (2)

A1exandr Belan
A1exandr Belan

Reputation: 4780

Lodash if you don't mind.

The task can be divided into two steps:

  • Renaming the object properties. I used the easiest way, but you are free to choose.
  • Merging objects. I used the lodash defaultsDeep method.

const salesLabelData = {"salesData": [{"id": "weekly","chartData": {"dataSets": [{"borderColor": "#2E87A8","backgroundColor": "#2E87A8","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"borderColor": "#951DAC","backgroundColor": "#951DAC","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"borderColor": "#FA9610","backgroundColor": "#FA9610","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"}]}},{"id": "monthly","chartData": {"dataSets": [{"id": "target-qty","borderColor": "#2E87A8","backgroundColor": "#2E87A8","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"id": "net-sales","borderColor": "#951DAC","backgroundColor": "#951DAC","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"id": "gap","borderColor": "#FA9610","backgroundColor": "#FA9610","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"}]}}]};
const salesAPIData = {"salesData": [{"id": "weekly","chartData": {"labels": ["Jan","Feb","Mar","Apr","May","Jun","July","Aug","Sep","Oct","Nov","Dec"],"datasets": [{"id": "target-qty","type": "bar","label": "Target Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "net-sales","type": "bar","label": "Net Sales Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "gap","type": "line","label": "Gap","data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]}]}},{"id": "monthly","chartData": {"labels": ["Jan","Feb","Mar","Apr","May","Jun","July","Aug","Sep","Oct","Nov","Dec"],"datasets": [{"id": "target-qty","type": "bar","label": "Target Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "net-sales","type": "bar","label": "Net Sales Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "gap","type": "line","label": "Gap","data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]}]}}]}


const renameProperties = (obj) => 
   JSON.parse(JSON.stringify(obj).replaceAll('"dataSets":','"datasets":'));

const result = _.defaultsDeep(renameProperties(salesLabelData), salesAPIData);


console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Upvotes: 1

trincot
trincot

Reputation: 350770

You'll need to have a kind of deep merge. It seems that we can assume that:

  • the data types of data that occurs in the same place in both data structures, are guaranteed to be the same;
  • the arrays that occur in the same place in both data structures, are guaranteed to have the same size;
  • the primitive values that occur in the same place in both data structures (strings, numbers, ...) are guaranteed to be the same.

It's too bad that you want to merge properties that have different names (dataSets, datasets), so some code is needed to deal with that. But it would be better to correct this at the source.

Here is some suggested code:

function deepMerge(a, b) {
    if (Object(a) !== a) return b;
    if (Object(b) !== b) return a;
    if (Array.isArray(a)) return a.map((obj, i) => deepMerge(obj, b[i]));
    if (a.hasOwnProperty("dataSets")) { // "fix"
        let dataSets;
        ({ dataSets, ...a } = { ...a, datasets: dataSets });
    }
    return Object.fromEntries(Array.from(
        new Set(Object.keys(a).concat(Object.keys(b))), 
        key => [key, deepMerge(a[key], b[key])]
    ));
}

var salesLabelData = {"salesData": [{"id": "weekly","chartData": {"dataSets": [{"borderColor": "#2E87A8","backgroundColor": "#2E87A8","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"borderColor": "#951DAC","backgroundColor": "#951DAC","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"borderColor": "#FA9610","backgroundColor": "#FA9610","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"}]}},{"id": "monthly","chartData": {"dataSets": [{"id": "target-qty","borderColor": "#2E87A8","backgroundColor": "#2E87A8","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"id": "net-sales","borderColor": "#951DAC","backgroundColor": "#951DAC","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"},{"id": "gap","borderColor": "#FA9610","backgroundColor": "#FA9610","fill": "false","pointRadius": "3","pointHoverRadius": "4","borderWidth": "2"}]}}]};

var salesAPIData = {"salesData": [{"id": "weekly","chartData": {"labels": ["Jan","Feb","Mar","Apr","May","Jun","July","Aug","Sep","Oct","Nov","Dec"],"datasets": [{"id": "target-qty","type": "bar","label": "Target Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "net-sales","type": "bar","label": "Net Sales Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "gap","type": "line","label": "Gap","data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]}]}},{"id": "monthly","chartData": {"labels": ["Jan","Feb","Mar","Apr","May","Jun","July","Aug","Sep","Oct","Nov","Dec"],"datasets": [{"id": "target-qty","type": "bar","label": "Target Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "net-sales","type": "bar","label": "Net Sales Qty","data": [450, 480, 379, 325, 425, 287, 274, 499, 333, 401, 123, 444]},{"id": "gap","type": "line","label": "Gap","data": [450, 480, 470, 420, 425, 436, 401, 411, 422, 433, 499, 444]}]}}]}

let result = deepMerge(salesLabelData, salesAPIData);

console.log(result);

Upvotes: 3

Related Questions