Create a dynamic 2D grid structure by parsing JSON data with different column sizes

I have a JSON data set that needs to be structured into a 2D array format. The number of columns is determined dynamically after iterating over the JSON, and they are labeled as #1, #2 for multiple occurrences within each item. The expected output should be in the form of a 2D array.

The desired structure of the array is:

[
    ["firstName", "middleName", "lastName", "addresses: #1 type", "addresses: #1 poBox", "addresses: #1 streetAddress", "addresses: #1 city", "addresses: #1 region", "addresses: #1 postalCode", "addresses: #1 country", "addresses: #2 type", "addresses: #2 poBox", "addresses: #2 streetAddress", "addresses: #2 city", "addresses: #2 region", "addresses: #2 postalCode", "addresses: #3 poBox", "addresses: #3 region", "addresses: #3 postalCode", "addresses: #2 country", "photos: #1 url", "photos: #1 default", "photos: #2 url", "photos: #2 default"],
    ["John", "Joseph", "Briggs", "home", 111, "", "City1", "", "1ER001", "USA", "work", 222, "", "City2", "Region2", "1ER002", "", "", "", "", "photo.org/person1", "TRUE", "photo.org/person1", "TRUE"],
    ["Bill", "", "Thatcher", "home", "", "", "City3", "Region3", "1ER003", "USA", "work", 444, "", "", "Region4", "1ER004", 555, "Region5", "1ER005", "", "", "", ""]
]

A visual representation of the expected output can also be viewed here.

Please note that the red header columns do not contain any data and should not be included in the 2D array output. There are approximately 1000 rows with similar data patterns where some entries may be missing fields such as a postal code, middle name, or photos.

You can view an image of the data structure here.

<!DOCTYPE html>
<html>

<body>
<script>



var crowds = [{
        "name": [{
            "firstName": "John",
            "middleName": "Joseph",
            "lastName": "Briggs"
        }],
        "addresses": [{
                "type": "home",
                "poBox": "111",
                "city": "City1",
                "postalCode": "1ER001",
                "country": "USA"
            },
            {
                "type": "work",
                "poBox": "222",
                "city": "City2",
                "region": "Region2",
                "postalCode": "1ER002"
            }
        ],
        "photos": [{
                "url": "photo.org/person1",
                "default": true
            },
            {
                "url": "imagur.org/person1",
                "default": true
            }
        ]
    },
    {
        "name": [{
            "firstName": "Bill",
            "lastName": "Thatcher"
        }],
        "addresses": [{
                "type": "home",
                "city": "City3",
                "region": "Region3",
                "postalCode": "1ER003",
                "country": "USA"
            },
            {
                "type": "work",
                "poBox": "444",
                "region": "Region4",
                "postalCode": "1ER004"
            }
            {
                "poBox": "555",
                "region": "Region5",
                "postalCode": "1ER005"
            }            
        ]
    }
]



var rows = [];
var headerRow = [];


crowds.forEach(function(crowd) {
    var cols = [];
    for (key in crowd) {
        headerRow.push(key + ":#")
        cols.push(crowd[key].firstName)
                cols.push(crowd[key].middleName)
                        cols.push(crowd[key].lastName)
    }
    rows.push(cols)
})

console.log(JSON.stringify(headerRow.concat(rows)))

</script>
</body>

</html>

Answer №1

Consider

function restructureData(data, result = {}, key = '') {
    let addKey = (delimiter, segment) => key ? key + delimiter + segment : segment;

    if (Array.isArray(data))
        data.forEach((value, index) => restructureData(value, result, addKey(' #', index + 1)))
    else if (typeof data === 'object')
        Object.entries(data).forEach(([prop, value]) => restructureData(value, result, addKey(': ', prop)))
    else
        result[key] = data;
    return result;
}

applied to your information

let restructuredData = crowds.map(item => restructureData(item));
console.log(restructuredData);

this will generate a list of "restructured" objects similar to this:

[
  {
    'name #1: firstName': 'John',
    'name #1: middleName': 'Joseph',
    'name #1: lastName': 'Briggs',
    'addresses #1: type': 'home',
    ...etc
  },
  {
    'name #1: firstName': 'Bill',
    'name #1: lastName': 'Thatcher',
    'addresses #1: type': 'home',
    ...etc
  }
]

Next, you need to compile all keys from all restructured objects:

function mergeKeys(objects) {
    let keys = objects.reduce((acc, obj) => acc.concat(Object.keys(obj)), []);
    return [...new Set(keys)];
}

let combinedKeys = mergeKeys(restructuredData);

and finally create a table using the compiled keys:

let table = restructuredData.map(object => combinedKeys.map(key => object[key] ?? ''));

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

What is the best way to rotate a ThreeJS Object3D object around its endpoint?

Can an Object3D object be rotated around its end point? I located the center of my object using const boundingBox = new THREE.Box3().setFromObject(this.object). Would rotating at a specific point involve moving the object to that point, rotating it, and ...

The data-tooltip feature displays information as [Object object]

There seems to be an issue with displaying text in the data-tooltip. Instead of showing the intended message, it is displaying [Object object]. import React from "react"; import { FormattedMessage } from "react-intl"; const translate = (id, value={}) = ...

React, Axios, and the PokeAPI are like a team of explorers navigating an

Trying to enhance my React abilities, I decided to follow this tutorial on creating a list of names using PokeAPI. However, I hit a roadblock at 11.35 into the tutorial while implementing the provided code snippets in both App.js and PokemonList.js: fu ...

Unit testing Angular SVG to retrieve the SVGLengthList

Hello everybody! I am in need of some assistance regarding SVG. I am currently working on writing unit tests and I need to add an object with the type SVGLengthList to a method. I have gone through the documentation provided by W3, however, I am unsure of ...

I am having trouble loading content properly in a three-level panel menu on a website that uses Javascript

Currently facing a small issue with the navigation system I'm trying to incorporate on my website. Here is how it's coded: HTML <div class="panel1"> first navigation ul li set </div> <div class="panel2" id="subnav"> AJ ...

JavaScript Filtering Technique

Attempting to compose an array of names for a search output page The json arrangement looks like this: data = { "artists": [ { "artistName": "a" }, { "artistName": "b" }, { "artistName": "c" }, { "artistName": "d" }, { "artistName" ...

Enhancing the basic Error class through hooking and monkey-patching

Is there a way to customize the behavior of the Error class in JavaScript? I need to replace it with a custom class that adds additional fields and logic whenever someone tries to throw an error or any subclass of Error in my code base. This kind of custo ...

Finding your way to a particular section within a webpage through an external source

Hey there! I'm currently working on creating a link that will direct users to a specific section within my webpage. For example, redirecting them to https://blabla.github.io/my-website. My code is quite straightforward and it functions properly when ...

Using JavaScript to track changes in the document's appearance

Is there a method to determine when the visual presentation of the document has been altered? For instance: $(document).on('change??', function () { console.log('My appearance has changed'); }); // Modifying the appearance of a spe ...

Is there a way in Vue to switch between encrypted and unencrypted content in an input field?

I'm grappling with the challenge of creating an input field where the contents are initially hidden as 'ab****gh' and can be toggled to reveal as 'abcdefgh' upon a click. I've been experimenting with some code, but I'm st ...

Angular controller filter issue causing unexpected behavior

Within my Angular controller, I am utilizing a filter in a specific manner. My intention is to filter only $scope.codeSubFiltered, while leaving $scope.codeSub unaffected. However, after applying the filter, both $scope.codeSub and $scope.codeSubFiltered ...

Exploring Vue Components Through the Global Scope

Is it feasible to retrieve an instantiated Vue.js component object from the global JavaScript scope with Vue.js, or are these objects encapsulated within Vue's internals? For instance, when I have code defining a component like this: Vue.component(&a ...

Automatically updating the scope of the .filter() function

Is there a way to update the filter in the code below? .controller('MainCtrl', ["$rootScope", "$scope", function($rootScope, $scope) { $rootScope.number = 1; $scope.text = "foo|baz|bar" }]).filter("MyFormat", ["$rootScope", function($rootS ...

Uh oh, here we go again. Dealing with another Vk Api

Things were going smoothly until I encountered a JSON that has left me feeling frustrated. I am attempting to retrieve user songs, but I am struggling with the JSON format. Here is the JSON data: response: { count: 529, items: [{ id: '34', pho ...

Encountering issues with the setValue function in Nightwatch

Currently, I am in the process of setting up a new Nightwatch project to automate a basic Google search page. The assertion for searchbox present on page is successful, but I am facing difficulties performing any mouse or keyboard actions on the elements ( ...

Distinguishing between an array of struct pointers and using malloc with struct pointers

working example: struct information{ int value; }; int main(void){ struct information *array[2]; (*array)->value = 6; printf("%d\n", (*array)->value); return 0; } segfault explanation: struct information{ int value; } ...

Convenient methods in Three.js for easily detaching and attaching character weapons within a scene

I'm currently facing challenges while developing a first-person shooter game using Three.js. I've encountered major glitches with THREE.SceneUtils.detach() and THREE.SceneUtils.attach(), and I'm uncertain if they are the appropriate methods ...

Encountering an issue with ddclient while attempting to run it in debug mode for troubleshooting purposes

Recently, after installing centOS 6 on my system, I decided to set up ddclient in order to update my DNS records on Cloudflare. Despite following the instructions provided on the Cloudflare site and other tutorials, when I attempted to run the debug comman ...

Iterate through the form fields and save the information into an object

I am attempting to create a JavaScript object by looping through form inputs. const data = {}; // loop through each input found in form $('#form_name').filter(':input').each(function() { const $id = $(this).attr('id'); c ...

Tips for displaying a populated ViewBag string from a try/catch block on the screen

I'm currently working on parsing a JSON file in my controller and implementing try/catch functionality for any errors that may arise. When an error occurs during the JSON parsing process, I populate ViewBag with the error message and attempt to displa ...