-1

Here is my array , I need to loop through this array and check if objects with same docId exists and if they do, I have to combine jArray of these objects

FinalArray = [
    {
        "jArray": [
            {
                "Cd": "A"
            }
        ],
        "Ref": {
            "docId": "123"
        },
        "name": "bene",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    },
    {
        "jArray": [
            {
                "Cd": "A"
            }
        ],
        "Ref": {
            "docId": "456"
        },
        "name": "leg",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    },
    {
        "jArray": [
            {
                "Cd": "B"
            }
        ],
        "documentRef": {
            "docId": "123"
        },
        "name": "bene",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    },
    {
        "jArray": [
            {
                "Cd": "B"
            }
        ],
        "Ref": {
            "docId": "456"
        },
        "name": "leg",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
  },
  {
        "jArray": [
            {
                "Cd": "A"
            }
        ],
        "Ref": {
            "docId": "789"
        },
        "name": "hello",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    }
]

expected result is as below.

[
    {
        "jArray": [
            {
                "Cd": "A"
        },
        {
                "Cd": "B"
        }
        ],
        "Ref": {
            "docId": "123"
        },
        "name": "bene",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    },
    {
        "jArray": [
            {
                "Cd": "A"
        },
        {
                "Cd": "B"
        }
        ],
        "Ref": {
            "docId": "456"
        },
        "name": "leg",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    },
  {
        "jArray": [
            {
                "Cd": "A"
            }
        ],
        "Ref": {
            "docId": "789"
        },
        "name": "hello",
        "check1": false,
        "check2": false,
        "check3": false,
        "check4": false,
        "id": "0001"
    }
]

any thoughts of how to achieve this ? how do i loop through an array and compare object values to combine respective arrays

I've been trying to do something like below. but can't figure out the right way

FinalArray.map((object, index) => {
          if (object.Ref.docId === FinalArray[index + 1].Ref.docId) {
            const tempJArray = object.jArray.concat(FinalArray[index + 1].jArray);
Object.assign(tempJArray , jArray);
            Object.assign({}, object.Ref.docId, FinalArray[index + 1].Ref.docId);

          }
        });
aki
  • 175
  • 1
  • 3
  • 14

2 Answers2

1

Much similar to a recent answer by me about "group array of objects by key" using reduce

var FinalArray = [{"jArray":[{"Cd":"A"}],"Ref":{"docId":"123"},"name":"bene","check1":false,"check2":false,"check3":false,"check4":false,"id":"0001"},{"jArray":[{"Cd":"A"}],"Ref":{"docId":"456"},"name":"leg","check1":false,"check2":false,"check3":false,"check4":false,"id":"0001"},{"jArray":[{"Cd":"B"}],"documentRef":{"docId":"123"},"name":"bene","check1":false,"check2":false,"check3":false,"check4":false,"id":"0001"},{"jArray":[{"Cd":"B"}],"Ref":{"docId":"456"},"name":"leg","check1":false,"check2":false,"check3":false,"check4":false,"id":"0001"},{"jArray":[{"Cd":"A"}],"Ref":{"docId":"789"},"name":"hello","check1":false,"check2":false,"check3":false,"check4":false,"id":"0001"}];

var before = JSON.stringify(FinalArray);


var obj = FinalArray.reduce(function(agg, item) {
  var docId = item.Ref && item.Ref.docId || "other"
  var copy = [...item.jArray];
  if (!agg[docId]) {
    agg[docId] = {
      jArray: [],
      Ref: { docId }, 
      name: item.name,
      id: item.id,
      // etc
    }
  }
  agg[docId].jArray = agg[docId].jArray.concat(copy)

  return agg;
}, {})

var result = Object.values(obj);
console.log(result)

var after = JSON.stringify(FinalArray);
console.log(before===after)
.as-console-wrapper {
  max-height: 100% !important;
}
IT goldman
  • 14,885
  • 2
  • 14
  • 28
  • This is modifying my FinalArray which i don't want. how do i avoid doing that – aki Aug 31 '22 at 00:28
  • I'll have a look later, but basically make a clone instead of this line: `agg[docId] = item;` – IT goldman Aug 31 '22 at 05:29
  • I just read the doc which says —“If existing elements of the array do get changed, the values passed to the callback function will be the values from the time that reduce() was first called on the array.” – aki Aug 31 '22 at 11:24
  • that worked just fine. i wonder if there's any other way to clone this object and then replace just the jArray, instead of manually setting each item like this agg[docId] = { jArray: [], Ref: { docId }, name: item.name, id: item.id, // etc } – aki Aug 31 '22 at 12:48
  • so we don't have to worry about the object except for jArray. – aki Aug 31 '22 at 12:56
  • You can clone it, however as `jArray` is nested I suspected it might not get copied in a shallow copy. Same for `Ref`. – IT goldman Aug 31 '22 at 13:03
  • I could do it like this if (!agg[docId]) { agg[docId] = cloneDeep(item); agg[docId].jurisdictionArray = []; } by using lodash cloneDeep. Thanks a lot for helping on this – aki Aug 31 '22 at 13:24
1

using lodash cloneDeep to copy obj

Above solution worked just fine. But , I only replaced if block code so i don't have to map object values manually (don't have to worry about other key value in the obj)

if (!agg[docId]) {
            agg[docId] = cloneDeep(item);
            agg[docId].jArray = [];
          }
aki
  • 175
  • 1
  • 3
  • 14