Home > front end >  How to combine 2 nested array of object values
How to combine 2 nested array of object values

Time:03-16

How do I combine 2 nested arrays. There are 2 Array A and B

const A = [
  {
    "id": 0,
    "bp": true,
    "ba": "value1",
    "risk": [
      {
        "id": 0.1,
        "rk": false,
        "title": "risk1",
        "control": [
          {
            "id": 0.12,
            "ctl": "ctl1"
          },
          {
            "id": 0.13,
            "ctl": "ctl2"
          }
        ]
      },
      {
        "id": 0.1223,
        "rk": false,
        "title": "risk23"
      }
    ],
    "master": [
      {
        "id": 0.2,
        "mk": false,
        "title": "obli1",
        "control": [
          {
            "id": 0.12,
            "ctl": "ctl1"
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "bp": true,
    "ba": "value2"
  }
]

.

const B = [
      {
        "id": 0,
        "bp": true,
        "ba": "value1",
        "risk": [
          {
            "id": 0.1,
            "rk": false,
            "title": "risk1",
            "control": [
              {
                "id": 0.12,
                "ctl": "ctl1"
              },
              {
                "id": 0.13,
                "ctl": "ctl2"
              }
            ]
          }
        ],
        "master": [
          {
            "id": 0.2,
            "mk": false,
            "title": "obli1",
            "control": [
              {
                "id": 0.12,
                "ctl": "ctl1"
              }
            ]
          },
          {
            "id": 0.211,
            "mk": true,
            "title": "obli44",
            "control": [
              {
                "id": 0.12,
                "ctl": "ctl1"
              }
            ]
          }
        ]
      },
      {
        "id": 3,
        "bp": true,
        "ba": "value3"
      }
    ]

.

on combining A and B the output should be of below format. We need to take risk from table A and we need to take master from table B and add it to table C.

The Final array looks like the following.

.

const c = [
  {
    "id": 0,
    "bp": true,
    "ba": "value1",
    "risk": [
      {
        "id": 0.1,
        "rk": false,
        "title": "risk1",
        "control": [
          {
            "id": 0.12,
            "ctl": "ctl1"
          },
          {
            "id": 0.13,
            "ctl": "ctl2"
          }
        ]
      },
      {
        "id": 0.1223,
        "rk": false,
        "title": "risk23"
      }
    ],
    "master": [
      {
        "id": 0.2,
        "mk": false,
        "title": "obli1",
        "control": [
          {
            "id": 0.12,
            "ctl": "ctl1"
          }
        ]
      },
      {
        "id": 0.211,
        "mk": true,
        "title": "obli44",
        "control": [
          {
            "id": 0.12,
            "ctl": "ctl1"
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "bp": true,
    "ba": "value2"
  },
  {
    "id": 3,
    "bp": true,
    "ba": "value3"
  }
]

The data can be more than 1000 records. please help me with which it will save time and complexity.

Thanks in Advance.

CodePudding user response:

The first thing you need to do is to isolate the IDs from array A and B. You can also map over the two of them concatenated together, but then you may have duplicate values. This seems like a rational way to go about ensuring single entries for each ID.

const allIds = [...a.map(x => x.id), ...b.map(x => x.id)];
const uniqueIds = allIds.reduce((prev, curr) => {
  return prev.includes(curr) ? prev : [...prev, curr]
}, []);

Then you need to take those uniqueIds, and map over each of them. For each ID, you need to return the matching object in A and the matching object in B, but overwrite the risk property with the value from the object in A and overwrite the master property with the value from the object in B.

That can be done by just finding the matching objects in A and B, and then use the spread operator to assign their entries to the new object.

Note: If the properties outside of risk and master (e.g. bp or ba) have different values, then the element listed last will overwrite it. In the below case, that means if the bp value in A is true and the bp value in B is false, then the bp value in C will be false.

const c = uniqueIds.map(id => {
  const elementInA = a.find(x => x.id === id);
  const elementInB = b.find(x => x.id === id);
  return {
    ...elementInA,
    ...elementInB,
    risk: [
      ...elementInA?.risk ?? []
    ],
    master: [
      ...elementInB?.master ?? []
    ]
  };
});

CodePudding user response:

Instead of looping through multiple times both arrays, I would suggest something that will loop through each array, not more than needed.

The following approach will loop through twice the first array, and once the B array. (not considering the indexOf method).

const ids = A.map(({id}) => id), C = A.map(a => a);

for(let b of B){
    let index = ids.indexOf(b.id);
    if(index < 0){
        C.push(b);
    } else {
        C[index] = {
            ...A[index],
            ...b,
            risk: [
                ...A[index]?.risk ?? []
              ],
              master: [
                ...b?.master ?? []
              ] 
        }
    }
}
  • Related