Working with deeply nested objects in JavaScript

Given the following array structure:

  objNeeded = [
    {onelevel: 'first'},
    {
      onelevel: 'second',
      sublevels: [
        {onelevel: 'domain'},
        {onelevel: 'subdomain'}
      ]
    },
    {
      onelevel: 'third',
      sublevels: [
        {
          onelevel: 'fourth',
          sublevels: [
            {onelevel: 'domain'}
          ]
        }
      ]
    }
  ];

The objective is to transform it into this object structure:

  objNeeded = {
    first: true,
    second: {
      domain: true,
      subdomain: true
    },
    third: {
      fourth: {
        domain: true
      }
    }
  };

This transformation may involve more nested objects and additional items in the original array.

What approach can be used to achieve this using JavaScript or Typescript?

Answer №1

If you're facing a specific issue that requires recursion, it might be best to implement it for your use case. Due to the complexity of this problem, I won't delve into detailed explanations here. However, I've included some comments within the code for reference.

const objNeeded = [
    {onelevel: 'first'},
    {
      onelevel: 'second',
      sublevels: [
        {onelevel: 'domain'},
        {onelevel: 'subdomain'}
      ]
    },
    {
      onelevel: 'third',
      sublevels: [
        {
          onelevel: 'fourth',
          sublevels: [
            {onelevel: 'domain'}
          ]
        }
      ]
    }
  ];
  
  // Based on my understanding, the rules are as follows:
  // 1. If the value is a string, it becomes {[key]: true}
  // 2. If there are subLevels, we recursively build the sub arrays.

 function recursivelySetSubLevels(elements) {
   const output = {};
   
   elements.forEach(element => {
    
    if(!!element.sublevels) {
      
      output[element.onelevel] = recursivelySetSubLevels(element.sublevels);
      
    } else {
      
      output[element.onelevel] = true;
      
    }
   });
   
   return output;
 }
 
 console.log(recursivelySetSubLevels(objNeeded));

Answer №2

In this scenario, utilizing Array#reduce along with recursive calls can simplify the task at hand.

  1. With Array#reduce, you have the ability to transform the array into an object format efficiently.
  2. The recursive call is employed in order to delve into the inner sublevels of the data structure.

const neededObj = [{level: 'first'}, { level: 'second', sublevels: [ {level: 'domain'}, {level: 'subdomain'} ] }, { level: 'third', sublevels: [ { level: 'fourth', sublevels: [ {level: 'domain'} ] } ] } ];

const result = neededObj.reduce((acc, {
  level,
  sublevels
}) => (acc[level] = sublevels ? recursiveFunction(sublevels) : true, acc), {});

function recursiveFunction(array) {
  return Object.assign({}, ...array.map(({
    level,
    sublevels
  }) => ({
    [level]: sublevels ? recursiveFunction(sublevels) : true
  })))
}

console.log(result)

Answer №3

Here is a special function customConvert that can help you achieve your desired output.

Utilizing the for (obj of currentObj) loop allows us to iterate through the values in the array and perform the necessary object conversions.

By using Object.keys(obj), we are able to retrieve an array containing all the keys present in the object. Additionally, the .includes method checks if the provided value exists within the array.

The customConvert function employs recursion, triggering a recursive call when a current array object contains sublevels.

function customConvert(currentObj) {
  // initializing result object
  let result = {};

  // iterating through array values
  for (obj of currentObj) {
    // checking for sublevels in obj. Recursively call if found.
    if (Object.keys(obj).includes("sublevels")) {
      // retrieving converted object for the current object
      result[obj.onelevel] = customConvert(obj.sublevels, result[obj.onelevel]);
    } else {
      result[obj.onelevel] = true;
    }
  }

  // return the result
  return result;
}

let objRequired = [{onelevel: 'first'}, { onelevel: 'second', sublevels: [ {onelevel: 'domain'}, {onelevel: 'subdomain'} ] }, { onelevel: 'third', sublevels: [ { onelevel: 'fourth', sublevels: [ {onelevel: 'domain'} ] } ] } ];

console.log(customConvert(objRequired));

Answer №4

Here's an alternative approach:

const requiredObjects = [...];

const customReducerFunction = (accumulator, currentObject) => {
  if (currentObject.propertyOne) {
    accumulator[currentObject.propertyOne] = currentObject.subProperties && currentObject.subProperties.length
      ? currentObject.subProperties.reduce(customReducerFunction, {})
      : true;
  }
  return accumulator;
};

// Obtaining the necessary object
requiredObjects = objNeeded.reduce(customReducerFunction, {});

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

The Google OAuth profile response is lacking the Profile ID - NextAuth

I've been diving into a helpful tutorial on implementing roles in the next-auth session. However, I've encountered an issue where adding the profile property results in unexpected behavior with the profile being undefined. Additionally, there are ...

Fetching jQuery library via JavaScript

Having trouble loading the JQuery library from a JavaScript file and using it in a function. JS1.js $(document).ready(function () { //var id = 728; (function () { var jq = document.createElement('script'); jq.type = 'te ...

Troubleshooting problem with modifying Bootstrap button styling and hover effects

When creating a navigation menu with Bootstrap, I decided to change the buttons from the primary class to inverse. I then went on to further customize the inverse class using inline CSS to match my specific look and feel requirements. .btn-inverse { b ...

What is the best way to ensure that the bootstrap nav tab content fits perfectly on one line?

Check out this bootstrap navbar example You can see a screenshot here. <ul class="nav nav-tabs" style="display: inlne-block"> <li class="nav-item" style="text-align: center; display: inline;"> <div> <a class="nav ...

What is the best way to modify the state of a nested component?

I am facing a challenge in my React project where I have two buttons in my App.js. When either of the buttons is clicked, I want to change the current state (list) to display in descending order based on the button pressed (order by date or order by upvo ...

The issue persists with multiple instances of Swiper js when trying to use append and prepend functions

I'm encountering an issue with my swiper carousels on the page. Despite everything working correctly, I am facing problems with the append and prepend slide functions. When I remove this part of the code, everything functions as expected. $('.s ...

Encountering a MODULE NOT FOUND error when using express.js

const express = require("express"); const app = express(); const path = require("path"); app.use(express.static(staticPath)); let staticPath=path.join(__dirname, ".."); There seems to be an error in these lines of ...

Incorporate content upon button click using Javascript

Looking to create a unique Survey layout that includes: Question Name Options The question name is editable and can be changed with a click. Initially, there is one option with a checkbox to select it. This option should also update when clicked. Addit ...

Using TypeScript with React and Material-UI: Issue with undefined theme in createStyles()

Currently, I am delving into React with TypeScript and utilizing the Material UI framework for the frontend. In my quest to activate media queries, an error has crossed my path: Uncaught TypeError: Cannot read property 'up' of undefined ...

Conditionally typing in TypeScript to check if a string contains a specific value

Looking to create a function that takes a string as input and determines whether it contains '[]' or not. If it does, the function should return a list, otherwise an object. This is what I have so far: function customFunction<T = any>(input ...

Display information from an array in checkboxes. If the same data appears in another array, the corresponding checkbox in React will be automatically checked

I currently have two arrays. The first array, let's call it arr1, contains multiple objects such as [{"Name":"Mr.X"},{"Name":"Mr.Y"},{"Name":"Mr.Z"}]. The second array, named arr2, holds a few values like [{"Name":"Mr.Z"}]. My goal is to display all ...

Exploring into the subdirectory

I am trying to redirect to a subfolder ASPX page from the index.html page upon page load, but I am encountering an error with the following code: window.location.href = 'URL= HMIS/Login.aspx'</script> Error Resource cannot be found. D ...

The issue with the text not updating after upgrading to Vue 3 has not been

I am currently in the process of reworking a component for Vue 3, specifically using their new setup script to improve the code readability. This is what the current code looks like: export default { name: "typeWriter", data: () => { ret ...

What is the best way to use a generic callback function as a specific argument?

TS Playground of the problem function callStringFunction(callback: (s: string) => void) { callback("unknown string inputted by user"); } function callNumberFunction(callback: (n: number) => void) { callback(4); // unknown number inputt ...

Experiencing difficulties with $watch in my Angular controller

Having trouble getting a $watch function to work properly while testing a controller. In this scenario, the goal is to display ctrl.value in either ARI format or AEP format, but the underlying $scope.model is always kept in the ARI format. When ctrl.value ...

Postman is displaying [object object] as the return value, but the actual value is not

Currently, I am working on automating tasks using Postman One interesting aspect is the presence of a vehicles array in the body { "Vehicles":[ { "car":"{{car}}", "bike":"{{bike}}&quo ...

Is there a way to retrieve all the default CSS properties of the input checkbox tag using JavaScript?

Despite attempting to use console.log with JavaScript, my efforts were unsuccessful. Here is an example: console.log(document.getElementsByTagName('input')[0].attributes[0]) ...

Count up with HTML like a progressive jackpot's increasing value

I am interested in developing a progressive jackpot feature similar to the sample image provided. I would like the numbers to loop periodically. Can anyone advise me on how to achieve this effect? Any suggestions or examples, preferably using JavaScript o ...

showing a loading spinner while sending an ajax request, patiently awaiting the response, and preventing any further interactions on the page

On my page, I am utilizing multiple ajax calls to load specific parts of the response. However, I need to display a spinner on the section where the ajax call is being made to indicate that content is loading. Is there a way to create a universal method th ...

Session is required for req.flash() function in node.js to work properly

I recently started working with Node.js and I'm encountering an issue with sessions. I developed a simple application and tried to run it locally, but ran into some errors. Below are the details of my code along with the error messages: BAPS.js (app. ...