0

I have below two objects which I want to merge.

[
    {
        "response_code": 1,
        "response_message": [{
            "a": 1000,
            "b": 1000001,
            "c": 10000002
        }]
    }]
[
    {
        "response_code": 1,
        "response_message": [{
            "a": 2000,
            "b": 2000001,
            "c": 20000002
        }]
    }
]

I want to merge them like below by having only one value of response code and merge values of response message like below way.

{
    "response_code": 1,
    "response_message": [
    {
        "a": 1000,
        "b": 1000001,
        "c": 10000002
    },
    {
        "a": 2000,
        "b": 2000001,
        "c": 20000002
    }]
}

Really stuck with such complicated merging where I want only once the value of response code and merge the values of response message.

Here I want to remove response code value from other array and merge/group the response message value with fist array.

Nilesh
  • 518
  • 1
  • 9
  • 26
  • what did you try? Where are you stuck? – LEQADA Mar 16 '20 at 15:33
  • @LEQADA I am stuck where I want to remove response_code value from second array and need to merge response_message value with first array. I have tried functions from https://stackoverflow.com/questions/41395872/how-to-remove-duplicates-objects-from-array-in-javascript here. But its not givog expected format output, – Nilesh Mar 16 '20 at 15:38
  • If I understand you correctly that this array is just an example and you have much more possible values of "response_code" and many more items in this array, then this can not be done in single step, you need to build a whole algorithm that will transform these objects. – Eggon Mar 16 '20 at 15:43
  • @Eggon No. I will have only 0 if any type of error or 1 for success in response_code value. – Nilesh Mar 16 '20 at 16:09
  • The first response message is an array containing 1 object , second one is an array containing incorrect elements - neither objects nor single elements - which is correct? What do yu want to achieve putting a single object into an array (in the forst case)? – Eggon Mar 16 '20 at 16:35

4 Answers4

1

I whipped up a little function for you:

And in accordance with the concerns raised by you in the comments, along with the test case where response_message was a string, I have edited the code snippet to include multiple cases to test.

const inputs = [
    [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        },

        {
            "response_code": 1,
            "response_message": [{
                "p": 1000,
                "q": 1000001,
                "r": 10000002
            }]
        }
    ],
    [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        },
        {
            "response_code": 1,
            "response_message": 'No data'
        }
    ],
    [{
            "response_code": 1,
            "response_message": 'No data'
        },
        {
            "response_code": 1,
            "response_message": 'No data'
        }
    ]

]

const getGroupedArr = (arr) => {
    const codeMap = arr.reduce((cMap,obj) => {
        let existingMessageArr = cMap.get(obj.response_code);
        let arrayToAdd = Array.isArray(obj.response_message) ? obj.response_message : [];
        if(existingMessageArr){
            existingMessageArr.push(...arrayToAdd);
        } else {
            cMap.set(obj.response_code,arrayToAdd);
        }
        return cMap;
    },new Map());
    const iterator = codeMap[Symbol.iterator]();
    const resultArr = [];
    for (let item of iterator) {
        resultArr.push({
            response_code: item[0],
            response_message: item[1]
        })
    }
    return resultArr;
}

inputs.forEach((inputArr,index) => {
    console.log(`Result for input ${index+1}`,getGroupedArr(inputArr));
})

Notice that I used Map where in JS most people prefer objects because maps in JS are iterable, but with an object I would've had to do an extra Object.keys() step, so this makes is slightly more efficient than the object approach, though a little more verbose.

Also note that in the third case, when no object with a particular response_code has any data, the result would be an empty array rather than a string. In weakly typed environments like JS, it is always a good practice to maintain some type consistency (which actually makes the input value of 'No data' in response_code not ideal), otherwise you may need to put type checks everywhere (like in the edited funciton in the above snippet).

Same function can be used in a contraint you mentioned in the comments, when the objects with same response_code exist in two different arrays (the two input arrays can simply be merged into one):

const inputArr1 = [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        }]

const inputArr2 = [{
            "response_code": 1,
            "response_message": [{
                "p": 1000,
                "q": 1000001,
                "r": 10000002
            }]
        }]

const getGroupedArr = (arr) => {
    const codeMap = arr.reduce((cMap,obj) => {
        let existingMessageArr = cMap.get(obj.response_code);
        let arrayToAdd = Array.isArray(obj.response_message) ? obj.response_message : [];
        if(existingMessageArr){
            existingMessageArr.push(...arrayToAdd);
        } else {
            cMap.set(obj.response_code,arrayToAdd);
        }
        return cMap;
    },new Map());
    const iterator = codeMap[Symbol.iterator]();
    const resultArr = [];
    for (let item of iterator) {
        resultArr.push({
            response_code: item[0],
            response_message: item[1]
        })
    }
    return resultArr;
}


console.log(getGroupedArr([...inputArr1,...inputArr2]));
Anuj Pancholi
  • 1,153
  • 8
  • 13
  • When I am running above code I am getting below output, [ { response_code: 1, response_message: [ [Object], [Object] ] } ]. Also when I run the same code for below input. const inputArr = [ { "response_code": 1, "response_message": [{ "a": 1000, "b": 1000001, "c": 10000002 }] }, { "response_code": 1, "response_message": 'No data' } ] --> Output is [ { response_code: 1, response_message: [ [Object], 'N', 'o', ' ', 'd', 'a', 't', 'a' ] } ] – Nilesh Mar 16 '20 at 18:01
  • I was running on the assumption that `response_message` was going to be an array, not a string, from the info in the question. If there is no data available, an empty array or null would better represent that. Also, in the first case, you must be using `console.log()`, which will display `[Object]` for nested object in Node.js, but rest assured, your object is there in memory. Try `console.log(JSON.stringify(getGroupedArr(inputArr)))` – Anuj Pancholi Mar 17 '20 at 03:12
  • I have edited the answer to better suit your needs, please have a look. – Anuj Pancholi Mar 17 '20 at 03:35
  • Hi Anuj, My problem is I have same keys in diff arrays. I have solved the scenario where I am getting No data. But now I am facing an issue to merger the two arrays with same keys. Now what is happening is my second array is overriding a first array. I have edited a question now so that you can notice that I have two arrays with same keys. That I need to merge. I dont need to check for NO Data scenario here now as I have handled it in diff way. – Nilesh Mar 17 '20 at 18:45
  • Have added a snippet (see edited answer) where I have merged the arrays while passing the parameter to the function and it works. – Anuj Pancholi Mar 18 '20 at 06:08
  • Hi Anuj, Will that code work for arrays with same keys. – Nilesh Mar 18 '20 at 08:10
  • Hi Anuj, I have added a my code through which I have resolved the issue. But thanks a lot for helping with your inputs. – Nilesh Mar 18 '20 at 17:04
0

I think you're looking for a groupby.

Check this good old post from stackoverflow and be aware of the different answers/ implementaions: Most efficient method to groupby on an array of objects

JulioSa
  • 118
  • 1
  • 6
0
    const arrayOf0 = yourArray.filter(item => item.response_code===0)
    const arrayOf1 = yourArray.filter(item => item.response_code===1)
    const merged0 = {response_code: 0, response_message: []};
    const merged1 = {response_code: 1, response_message: []};
    arrayOf0.forEach(item => { 
merged0.response_message.push(item.response_message[0]
}) 
    arrayOf1.forEach(item => {
 merged1.response_message.push(item.response_message[0]
})

Something like this?

Eggon
  • 2,032
  • 2
  • 19
  • 38
  • It is giving me same output the way I am getting already. No change in format. – Nilesh Mar 16 '20 at 18:06
  • I'm sorry, bu what output you expect? This is what you described you wanted – Eggon Mar 16 '20 at 18:11
  • When I run above code it gave me below output. [ { response_code: 1, response_message: [ [Object] ] }, { response_code: 1, response_message: 'No data' } ]. I would need to display response code only once. Input was like this const inputArr = [ { "response_code": 1, "response_message": [{ "a": 1000, "b": 1000001, "c": 10000002 }] }, { "response_code": 1, "response_message": 'No data' } ] – Nilesh Mar 16 '20 at 18:22
  • The output you want is in `merged0` and `merged1` constants. Have you checked THEM? They can't look what you wrote, because the code doesn't work like this. – Eggon Mar 16 '20 at 18:31
  • The code I provided should output exactly that in the `merged1` constant – Eggon Mar 17 '20 at 19:29
0

I have resolved the array merging by below code.

      const mergedArray = [];
      myarray.forEach((obj, index) => {
        var newObj = {}
        if(index > 0){
          if(mergedArray.length > 0){
            for(let i=0; i<obj.response_message.length;i++){
              mergedArray[0].response_message.push(obj.response_message[i]);
            }
          }
        }else{
          newObj["response_code"] = obj.response_code ;
          newObj["response_message"] =  obj.response_message;
          mergedArray.push(newObj);
             }
      })
Nilesh
  • 518
  • 1
  • 9
  • 26