Transform complex nested object structure

What is the optimal method to transform ... ?

const obj = {
  A: { B: [0, 0, 0, 0] },
  D: {
    B: [0, 0, 0, 0],
    C: [0, 0, 0, 0]
  }
}

into

const obj = {
  "A - B": [0, 0, 0, 0],
  "D - B": [0, 0, 0, 0],
  "D - C": [0, 0, 0, 0]
}

Thank you for your consideration

Edit: I apologize. I have corrected the question. It is required for all pairs in a nested object. The depth remains constant

Answer №1

To achieve this task, you can utilize the methods Object.entries() and reduce().

const obj = {
  A: {
    B: [0, 0, 0, 0]
  },
  D: {
    B: [0, 0, 0, 0],
    C: [0, 0, 0, 0]
  }
};

var result = Object.entries(obj).reduce((acc, [key, value]) => {
  Object.entries(value).forEach(([subKey, subValue]) => {
    acc[key + ' - ' + subKey] = subValue;
  });

  return acc;
}, {});

console.log(result);

Answer №2

One way to address nested objects in a dynamic manner is by keeping track of the path, base object, and actual object.

function removeNested(object, path = [], base = object) {
    Object.entries(object).forEach(([k, v]) => {
        if (v && typeof v === 'object' && !Array.isArray(v)) {
            removeNested(v, [...path, k], base);
        } else {
            base[[...path, k].join(' - ')] = v;
            delete base[path[0]];
        }
    });
}

const obj = { A: { B: [0, 0, 0, 0] }, D: { B: [0, 0, 0, 0], C: [0, 0, 0, 0] } };

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

Answer №3

Simple solution

Here is one approach:

const convert = (obj) => 
  Object.entries(obj)
    .reduce((acc, [key1, val]) => Object.keys(val)
      .reduce((acc, key2) => ({
        ...acc,
        [`${key1} - ${key2}`]: val[key2]
      }), acc), {})

const obj = {A: { B: [0, 0, 0, 0] }, D: {B: [0, 0, 0, 0], C: [0, 0, 0, 0]}}

console.log(convert(obj))

Recursive paths

We can also create a recursive version to handle any depth of objects.

// helper function
const findPathsToLeaves = (object, path = [[]]) => 
  typeof object == 'object' && !(Array.isArray(object))
    ? Object.entries(object).flatMap(([key, value]) => findPathsToLeaves(value, path).map(p => [key, ...p]))
    : path

// main function
const convert= (obj) => 
  findPathsToLeaves(obj).reduce((acc, pathToLeaf) => ({
    ...acc, 
    [pathToLeaf.join(' - ')]: pathToLeaf.reduce((o, p) => (o || {})[p], obj)
  }), {})

// example usage
const obj = {
  A: { B: [0, 0, 0, 0] },
  D: {
    B: [0, 0, 0, 0],
    C: [0, 0, 0, 0],
    E: {
      F: 42
    }
  }
}

console.log(convert(obj))

This implementation includes a helper function called findPathsToLeaves, which finds the paths to all leaf nodes in an object. The main function then uses these paths to create a new object with keys corresponding to the leaf paths and their respective values from the original object.

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

Using AngularJS to invoke the ng-required directive and trigger a function

Is it possible to make the required value dependent on a function? Something similar to this? I need to achieve this in order to dynamically change the required attribute for form inputs... HTML: Name: <input type="text" ng-model="user.name" ng-r ...

Dealing with 401 Errors: Navigating Redirects using Vue.js and

Currently, I am utilizing Vue.js along with axios in an attempt to create a generic API object as shown below: import router from './router' import auth from './auth' const axios = require('axios') export const API = axios.c ...

Guide on utilizing direction.set within threejs for Vector3 types

In the code below, I have defined a plane, wall, and a character. Now, I am trying to set the direction using vector3(). However, I seem to be encountering an issue. Whenever I press the left or right arrow key on the keyboard, I keep receiving the follow ...

Transferring information to the controller and refreshing the interface (Single-page design)

I'm stuck on a personal project and could really use some help. If anyone has any feedback, it would be greatly appreciated. Thanks in advance. In my index.php file, I have a div with the id main-container. Inside this container, there are two separa ...

Using AsyncStorage as a dependency in React Native to trigger the useEffect hook

I'm currently developing a react native authentication screen and I've encountered an issue with AsyncStorage where the token is not being retrieved in my Authentication.js screen after logging in. This results in the profile screen not loading a ...

I'm currently facing a conflict problem and I'm struggling to identify the root cause

I have integrated a date picker into my form, using the following resources: for the date picker plugin and 1.9.1 jquery.js for jQuery version. However, I encountered an error in this file: TypeError: $.isPlainObject is not a function if ( $.isPlainObje ...

Guide on setting the href value within a $.each loop in AJAX requests

I am struggling with downloading a file within a thread. The issue I'm facing is that I can't set the file name in the href and download attributes, so when I attempt to download it, it shows no file available. However, I did realize that replaci ...

Upon loading the page, a forward slash is automatically added to the end of the URL

My website has multiple pages of content, but I've noticed a strange issue with the URLs. When I navigate to example.com/guides, a forward slash is automatically added to the address bar, resulting in example.com/guides/. Surprisingly, the page still ...

Retrieve information and auto-fill text boxes based on the selected dropdown menu option

UPDATED QUESTION STATUS I'm currently working with Laravel 5.7 and VueJs 2.5.*. However, I am facing a challenge where I need to automatically populate form textboxes with data from the database when a dropdown option is selected. Despite my efforts ...

I'm receiving a TypeError in Nodejs indicating that the hashPassword function is not recognized as a function. Can anyone offer advice on how to

How's everything going? I could really use your assistance! I'm currently working on developing an API for registering authenticated users, with data storage in the MongoDB Atlas database (cloud). Unfortunately, I've run into a troubling er ...

The HTTP request is malfunctioning in a different location

I'm facing an issue where my code works in the w3schools code editor, but not on localhost or cpanel host. When I try to run it on another host, it gives me a bad request and doesn't return the answer. Here is the code snippet that I am working ...

`Is there a way for Javascript to retrieve information sent from Python Flask's render_template() method?`

Issue: I am facing difficulties in retrieving and displaying the data that I send from Javascript code when the user visits the site's landing page. The data in question is a dataframe. Backend Python Code: from flask import Flask, render_template, ...

Display or conceal a button in Angular 6 based on certain conditions

In my current project, I am facing a challenge where I need to disable a button while a task is running and then activate it once the task is complete. Specifically, I want a syncing icon to spin when the task status is 'In_progress' and then hid ...

The unhandled type error rises with each scroll I make

Having been diligently working on my current website project, I encountered a puzzling issue. Upon writing code to implement smooth scrolling throughout the site, I found myself facing a persistent error that continues to escalate with each scroll up or do ...

The texture rendered by Three.js WebGL is not displaying correctly on the plane and appears

Currently, I am working on a WebGL scene that consists of 2 planes. One of the planes displays a transparent texture perfectly, while the other plane is supposed to showcase a high-resolution, non-transparent texture as a background. Unfortunately, I am fa ...

The random number generator often omits both the upper and lower limits

I am working with an array that contains letters from A to H. However, when using a random number generator, I have noticed that the letters A and H are rarely selected. How can I adjust my approach to make sure these two bounds are included more often? ...

Searching for the search parameter in the Wordpress admin-ajax.php file. What could it

Just diving into the world of php and wordpress. Are there any search parameters I can include in admin-ajax.php? Here are the parameters in the ajax post; action: rblivep data[uuid]: uid_search_0 data[name]: grid_small_1 data[posts_per_page]: 8 data[pagin ...

Can I apply a universal babel configuration across all of my personal projects?

It becomes tedious to duplicate the same configuration file for each new project I start. ...

What is the process for importing DataTables using npm?

My attempt to import "datatables.net-select" using the usual method doesn't seem to be working. After checking the website, I found that the correct way to do it is: var $ = require( 'jquery' ); var dt = require( 'datatable ...

What is the best way to retrieve the input value from post.ejs?

app.js var express = require('express'); var bodyParser = require('body-parser'); var app = express(); var passport = require('passport'); var localStrategy = require('passport-local'); var axios = require("axi ...