Transforming a pair of lists into JSON format

I'm currently working on converting two lists into JSON format.

Let's take a look at an example:

list1 = ['a','b','a']
list2 = ['q','r','s']

The conversion should result in:

[{
    "name": "g",
    "children": [{
            "name": "a",
            "children": [{
                "name": "q"
            }, {
                "name": "s"
            }]
        },
        {
            "name": "b",
            "children": [{
                "name": "r"
            }]
        }
    ]
}]

I have come close with the following code:

list1 = ['a','b','a']
list2 = ['q','r','s']

nameDict = {}
childrenDict = {}

list1 = list1.map(x => {
  return({name: x});
});
console.log(list1);

list2 = list2.map(x => {
  return({children: x});
});
console.log(list2);

var combined = list1.map(function(e, i) {
  return [e, list2[i]];
});

console.log(JSON.stringify(combined))

However, the output is currently:

[[{"name":"a"},{"children":"q"}],
[{"name":"b"},{"children":"r"}],
[{"name":"a"},{"children":"s"}]]

Any suggestions on how to combine these elements into the desired format?

[{
    "name": "g",
    "children": [{
            "name": "a",
            "children": [{
                "name": "q"
            }, {
                "name": "s"
            }]
        },
        {
            "name": "b",
            "children": [{
                "name": "r"
            }]
        }
    ]
}]

Answer №1

Important Note: Due to the unknown origin of the letter g, I will focus solely on creating the root children array.

Given that both arrays are of equal length, a simple for loop can be used along with the array index to manipulate both arrays simultaneously. The approach involves constructing an array and checking during each iteration if the "child" already exists. If it does not, it is created.

l1 = ['a','b','a']
l2 = ['q','r','s']

let gChildren = []
for(let i = 0; i < l1.length; i++){
  let group = gChildren.find(c => c.name === l1[i])
  if(!group){
    group = { name: l1[i], children: [] }
    gChildren.push(group)
  }
  
  group.children.push({ name: l2[i] })
}

console.log(gChildren)

Answer №2

If you are looking to achieve the desired outcome while preserving your existing structure, the following code snippet will do just that:

let data1 = ["x","y","z"];
let data2 = ["1","2","3"];

let result = [{name: "group", elements: []}];

for (let i=0;i < data1.length;i++) {
        let match = false;
    for (let j=0;j < result[0].elements.length;j++) {
        if (result[0].elements[j].name === data1[i]) {
            result[0].elements[j].elements.push({name: data2[i]});
        match = true;
        }
      }
      if (match === false) {
            result[0].elements.push({name: data1[i], elements: [{name: data2[i]}]});
        }

}

console.log(JSON.stringify(result));

Answer №3

Using Array.prototype.reduce is a great strategy when you need to loop through an array and consolidate all values into a single output.

list1.reduce((accumulator, value, index) => {
  const correspondingValue = list2[index]
  const obj = accumulator.find(item => item.name === value)
  if (obj) {
    obj.children.push({name: correspondingValue})
  } else {
    accumulator.push({
      name: value,
      children: [{name: correspondingValue}]
    })
  }

  return accumulator
}, [])

This code efficiently adds children to an existing item or creates a new item if needed during each loop iteration.

The variable g is not included in this code snippet as its purpose is unknown. However, you can integrate the resulting array from the reduce function into another object or array as required.

Answer №4

If you want to rearrange the array and use the data as a path to the final child object, here is a way to do it:

arr1 = ['apple', 'banana', 'apple']
arr2 = ['queen', 'rook', 'knight']

After rearranging, it would look like this:

[
    ['apple', 'queen'], // apple -> queen
    ['banana', 'rook'], // banana -> rook
    ['apple', 'knight'] // apple -> knight
]

This arrangement can be used effectively with the reduce method.

One advantage of this method is that it can handle longer paths to the final children, such as:

[
    ['apple', 'x', 'y', 'z'],
    ...
]

When used with reduce, it returns a nested object with the specified relationship between the elements.

const
    rearrange = array => array.reduce((result, current) => current.map((value, index) => [...(result[index] || []), value]), []);

var arr1 = ['apple', 'banana', 'apple'],
    arr2 = ['queen', 'rook', 'knight'],
    finalResult = rearrange([arr1, arr2]).reduce((result, current) => {
        current.reduce((prev, element) => {
            var temp = (prev.children = prev.children || []).find(obj => obj.name === element);
            if (!temp) prev.children.push(temp = { name: element });
            return temp
        }, result);
        return result;
    }, { name: 'start' });

console.log(finalResult);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №5

A more concise version using distinct keys filter:

var list1 = ['a','b','a'], list2 = ['q','r','s']

var children = [...new Set(list1)].map(key => ({ name: key, children: 
        list2.filter((value, index) => list1[index] == key).map(value => ({ name: value })) }))

console.log( [{ name: 'group', children }] )

Alternatively, a more efficient approach with intermediate object groups:

var list1 = ['a','b','a'], list2 = ['q','r','s']

var children = Object.entries(
                       list1.reduce((obj, key, index) => ((obj[key] = obj[key] || []).push(list2[index]), obj), {})
                     ).map(([key, values]) => ({ name: key, children: values.map(value => ({ name: value })) }))

console.log( [{ name: 'group', children }] )

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

Check if the path meets the criteria to be considered valid JavaScript code

I have a javascript variable containing a path that may point to an image file, like ../app/assets/icon.png. If the path is incorrect or doesn't exist, I need to use a different file from another location. The final code should resemble this: var ver ...

How can Python be used to export hierarchical JSON data into an Excel xls file?

Looking to transfer data from Python to xlsx format. Currently have the data stored in JSON format. It doesn't matter what type of data is being exported out of Python. Here's an example JSON structure for a single article: { 'Word Coun ...

Using JavaScript to extract variables from parsed JSON data

Could someone please help me understand how to run this code smoothly without encountering any errors? var test = 'Something'; JSON.parse('{"xxx": test}'); I am inquiring about this because I have a JSON object containing variables th ...

Using JavaScript, you can employ the .split() and .replace() methods on a string value to accurately extract the specific

I'm currently attempting to extract hashtags from a text string by splitting it and removing unwanted HTML tags. Despite my efforts, I haven't been able to achieve the desired outcome. I am seeking guidance on where I might be going wrong. Here ...

What is the best way to display data from the Nuxt.js store?

I am new to Nuxt JS and following a tutorial on the Nuxt website. I created a store in store/index.js. export const state = () => ({ mountain: [], }) export const mutations = { addMountain(state, mountain) { state.mountain.push(mountain) }, } ...

Is it possible to link click and onchange events?

My code includes a function that updates an empty array and displays content in two separate HTML elements each time a radio button is selected from a select list. The content is displayed in a div and a ul element. Additionally, I want to display more rad ...

jQuery's Ajax feature fails to transmit information

I am facing an issue with my asp.net core backend project where my method is not receiving the data sent by jQuery ajax https://i.sstatic.net/O9wYg.png Here are the scripts I am using to send data: function ChangeCount(productId, count) { $.ajax({ ...

The problem with THREE JS OcclusionComposer: encountering "Cannot read properties of undefined (reading 'x')" error

I am attempting to replicate the Volumetric Lighting demonstration created by JMSWRNR but I am encountering difficulties with the Occlusion Composer. Since I am not well-versed in GLSL, debugging has proven to be quite challenging, especially for someone l ...

Serialization of JSON arrays using Jackson in Java

I've encountered a unique scenario where I'm attempting to serialize data using Jackson. Here is an example of the payload: { "key1": [ [ 10, 11 ], [ 12, 13 ] ...

Calculating numbers with Math.ceil will result in an increase of 1

After using Math.ceil, one value was rounded up to 50 and the other to 80. However, when I added these two values together, the result unexpectedly turned out to be 131. console.log(Math.ceil(e.currentTarget.clientHeight) // 50 console.log(Math.ceil(e.cu ...

Personalized labels for your JQuery Mobile sliders

Struggling to make this work correctly, I aim to introduce tick marks and custom labels into jQuery Mobile's slider widget. My goal is to add tick markers at 0, 25, 50, 75, and 100 with a unique string above each tick. Additionally, I want these label ...

The POST request is not functioning. An error has occurred: Unable to retrieve response data - no content is available for the preflight request

Having trouble making a post request from my client side to the back-end. Even with the new movie hardcoded, it keeps returning an error stating that there was a failure in loading the response data. Below is the code for the front-end: //Fetch request t ...

Incorporate chat functionality into Angular using an embedded script

Recently, I encountered an issue with inserting an online chat using a Javascript script into my website. My initial plan was to add it directly to my app.component.html, but unfortunately, it didn't display as expected. I'm now exploring option ...

How can you reset the chosen option in a Vue.js dropdown menu?

Within my dropdown menu, I have included a button that is intended to clear the selected city. Despite adding an event, the selected option is not being cleared. Can anyone provide insights on what I might be missing? Thank you in advance. Below is the bu ...

What is the best way to add an element before every child in a react jsx render function?

Below is the code snippet I am working with: class MessageList extends Component { render () { return ( <ul> { this.props.messages.map((message) => { return <Message key={message.id} message={message} ...

Having difficulty updating the state within a function

While working on developing a server-side pagination that mimics a static version, I have almost completed it. However, I have run into some issues that I am struggling to resolve. Here's how my code currently looks: const LiveIndex = (props) => { ...

Retrieve the rank of PySpark RDD and convert it into JSON format

My query in Hive returns data with Date, Name, Score1, Score2, and Avg_Score columns. I then convert this into an RDD using hive_context.sql(my_query).rdd. My goal is to transform this data into a JSON format with ranks based on the Avg_Score in descendin ...

"Using Mxgraph's getPrettyXml function does not retrieve the value of a custom

I’m having trouble with mxgraph’s getPrettyXml() not capturing the value of Custom elements. In my customized template, it looks like this: <add as="symbol"> <Symbol label="Symbol" description="" href="" data="{[hi :bill]}"> &l ...

Utilize jsonnet to update a nested list item in a list arrangement

This is my current JSON data: { "namespace": "monitoring", "name": "alok", "spec": { "replicas": 1, "template": { "metadata": "aaa", "spec": { "containers": [ { ...

Extracting Data from JSON Structures

I am struggling with extracting data from a JSON string that looks like this: var txt= '{“group”: [ {“family1”: { “firstname”:”child1”, “secondname”:”chlid2” }}, {“family2”: { ...