Combining JSON data the easy way

I am faced with the challenge of merging three JSON strings: JSON-A, JSON-B, and JSON-C. My goal is to combine JSON-A and JSON-B to form JSON-C, but also to split JSON-C back into JSON-A and JSON-B.

Below are the details of the JSONs:

JSON-A: - This contains questions along with all possible answers

{
"content": {
    "section": [
        {
            "questions": [
                {
                    "qText": "Have you or your family received medication or treatment for any serious conditions in the last 2 years?",
                    "qKey": 152,
                    "qType": [
                        {
                            "aType": "You",
                            "ans": [
                                {
                                    "aKey": "102",
                                    "aText": "Yes"
                                },
                                {
                                    "aKey": "106",
                                    "aText": "No"
                                }
                            ]
                        },
                        {
                            "aType": "Your family",
                            "ans": [
                                {
                                    "aKey": "108",
                                    "aText": "Yes"
                                },
                                {
                                    "aKey": "109",
                                    "aText": "No"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

JSON-B: - Selected answers

{
"qkey": "152",
"ans": [
    {
        "aType": "You",
        "aKey": "102"
    },
    {
        "aType": "Your family",
        "aKey": "106"
    }
]
}

JSON-C: - Output with selectedAnswer

{
"content": {
    "section": [
        {
            "questions": [
                {
                    "qText": "Have you or your family received medication or treatment for any serious conditions in the last 2 years?",
                    "qKey": 152,
                    "qType": [
                        {
                            "aType": "You",
                            "selectedAnswer": "102",
                            "ans": [
                                {
                                    "aKey": "102",
                                    "aText": "Yes"
                                },
                                {
                                    "aKey": "106",
                                    "aText": "No"
                                }
                            ]
                        },
                        {
                            "aType": "Your family",
                            "selectedAnswer": "109",
                            "ans": [
                                {
                                    "aKey": "108",
                                    "aText": "Yes"
                                },
                                {
                                    "aKey": "109",
                                    "aText": "No"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

To achieve this result from JSON-A and JSON-B, I implemented multiple nested loops which may appear complex. Is there a more efficient way to perform this task without using jQuery? Any suggestions or alternative methods would be greatly appreciated. Thank you!

Answer №1

Delving into the depths of four loops, check out this link: http://jsfiddle.net/xh7eLoL0/

qkey = jsonB.qkey;

jsonA.content.section.some(
    function CheckEachSection(section) {
        var found;

        found = section.questions.some(
            function FindMatchingQuestion(quest) {
                if (quest.qKey == qkey) {
                    jsonB.ans.forEach(
                        function ApplyEachAnswer(ans) {
                            quest.qType.some(
                                function FindEachMatch(sub) {
                                    if (sub.aType === ans.aType) {
                                        sub.selectedAnswer = ans.aKey;

                                        return true;
                                    }
                                });
                        });

                    return true;
                }
            });

        return found;
    });

Answer №2

Two suggestions. One idea is to consider restructuring the JSONB format either before receiving it or after to simplify lookups and eliminate unnecessary looping:

{
    "152": {
       "You": "102",
       "Your family": "106"
    }   
}

By transforming JSON-B into this structure post-receipt, you would only need to loop through it once instead of for every question.

Another recommendation is to explore using the forEach method on Array for improved readability.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

By incorporating both approaches and ensuring an answer exists for each question, you could potentially implement something like:

JSONA.content.section.forEach(function (section) {
    section.questions.forEach(function (question) {
        question.qType.forEach(function (qtype) {
            qtype.selectedAnswer = JSONB[question.qKey][qtype.aType]
        });
    });
});

Answer №3

Is this solution beneficial?

let sectionA = JSONA.content.section;
for(let sA in sectionA){
  let questionsA = sectionA[sA].questions;
  for(let qA in questionsA){
    let questionA = questionsA[qA], questionTypeA = questionA.qType;
    for(let b in JSONB){
      let jb = JSONB[b], jb_ans = jb.ans;
      if(jb.qKey === questionA.qKey){
        for(let bA in jb_ans){
          let jbA = jb_ans[bA];
          for(let aT in questionTypeA){
            let questionB = questionTypeA[aT];
            if(questionB.type === jbA.type){
              questionB.selectedAnswer = jbA.aKey;
            }
          }
        }
      }
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extract various .json fields and save them in a .txt file on a single line

Currently, I am using jq to convert a .json file into a text file. This is the command I used: jq -r '.[] | .file_id, .cases[].project.project_id' my_file.json > test6.tx The output file looks like this: d47c1aaa SKCM 5b8564e3 CESC 9b0b7 ...

Having trouble positioning a div in AngularJS so that it stays pixel-perfect regardless of browser resize or device orientation? Unfortunately, it's

I am a newcomer to AngularJS and have been struggling with a particular issue for several days now, leading me to suspect that I may be using it incorrectly. The problem at hand involves positioning 30 divs in a specific manner: 1) Each div should displa ...

I need help showing the JSON data from the API in my Go application

Currently, I am working with a small API that returns a JSON response containing a Todo object. I want to display this information in my Go web server. At the moment, all that is being shown is 'Todo', which is hard-coded. How can I replace this ...

Is there a way to programmatically activate a tooltip above an input field using JavaScript?

I am working on an ASP.NET web form that contains two input boxes. The requirement is that when the onkeypress event occurs in box A, a tooltip should pop up over box B. To achieve this functionality, I have included a JavaScript function in the onkeypres ...

What is the best way to trigger a new api call after the previous one has successfully completed?

I'm just starting to learn about Angular and RxJS, and I have a specific scenario that I'm struggling with. I need to make a new API call after a previous one is successfully resolved within the Angular/RxJS context, but I'm not sure how to ...

Adding an event listener to the built-in arrow buttons on the `<input type=number>` element is a simple way to enhance user interaction

<input type="number" id="test"> I'm trying to figure out how to set an event listener for the two arrow buttons on the right of this number input field. Typically, we can use jQuery like: $("#test").on("cl ...

Tips for inserting a variable into an attribute value when creating it using TypeScript

this.listvalue; list.forEach((v: any) => { v.data.forEach((v2: any) => { this.searchlist.push({ header: v.header, value: v2.value_0 }); }); }); Is there a way to replace v2.value_0 with v2.this.listvalue? I've tried ...

Creating a dynamic Xcode build process that automatically sets the version based on a JSON configuration file

Note: Currently working on a React Native project. Using Android and Gradle, I have successfully implemented the parsing of a JSON file to dynamically apply version values to the app during build time. The structure of the JSON file resembles this: { ...

Choose a chart from the dropdown menu and showcase it

I am facing a challenge in displaying two charts using a dropdown menu. I have attempted to achieve this using both JQuery and AngularJS, but I am encountering difficulties in making it work properly. There are two charts that need to be displayed: <d ...

Obtain a particular string line from a file using bash

I have a document containing text in a specific format [{"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"}, {"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","et ...

The useCallback hooks persist outdated values when the list is refreshed

Why am I not getting the expected values every time the function onRefresh is called using Hooks? Example when onRefresh is called twice: Expected values: true 0 20 false true 0 20 false Received values: false 0 0 false false 20 20 false Initial st ...

Python Client for Smart-on-FHIR Integration with Bundle Support

After obtaining a FHIR patient bundle JSON from the "$everything" operation, I am exploring the use of Smart on FHIR Python Client Models to simplify working with the data. You can find more information about the "$everything" operation here. One example ...

Can Pug Templating handle iterating through multiple arrays within a JSON data object?

Exploring Pug for the first time, I have been utilizing JSON files to store the data used in my Pug file. Here is an example of my data structure: { "nav": { "titles": [ "location", "reservations", "accomodations", "ameniti ...

Guide for extracting the button click text using selenium and node js, illustrated in the image

Attempting to extract the text displayed upon button click, as seen in the image. Below is the code I have used after accessing the website, however it failed to retrieve the text. //*[@class='']//*[text()=''] ...

Enable the ability to temporarily stop and then continue the ongoing upload process to Azure block storage

I've successfully implemented the feature to upload large files (up to 10gb in Azure block blob storage) by dividing them into small blocks and then committing them through commitblocklist. I found a helpful article that guided me through this process ...

Vue 2 - Error: The function is not defined at HTMLInputElement.invoker (vue.esm.js?65d7:1810)TypeError: cloned[i].apply

I encountered the following error: Uncaught TypeError: cloned[i].apply is not a function at HTMLInputElement.invoker (vue.esm.js?65d7:1810) I have set up my project using vue-cli (simple webpack), and below is the code for my component: <template ...

Is there a way to modify the response code that has already been dispatched?

I wrote this code with the intention of sending response headers quickly: const http = require('http'); const fs = require('fs'); const server = http.createServer((req, res) => { fs.readFile(/*file path*/, 'utf8', (err, ...

Converting a SQL query result into a JSON object can be accomplished by following these steps: extract the value for the "timestamp"

I am interested in using Cal-Heatmap to display my data, and currently my SQL query result looks like this: [ { "dateStampSecs": "1499637600", "value": "1" } ] However, I would like it to appear as follows: [ { "1499637600" : 1 } ] How can I merge them ...

Customize the DOM with tailwind CSS in a Vanilla JavaScript project

I am attempting to hide the "mark as complete" button and replace it with a "completed" button by switching the classes from "hidden" to "completed" and vice versa. However, when I use an event listener to manipulate the DOM with the code provided below, t ...

The necessity of ExpressJS

After reviewing the Express.JS 4.x API documentation, I became intrigued by their setup process. Here's my interpretation of how it works: In the provided sample code snippet from the Express.JS 4.x API, the express module is first imported and stored ...