Continue iterating using (forEach, map,...) until the object (children) has no more elements

I need to disable the active status for all elements within my object structure. Here is an example of my object:

const obj = 
  { name: 'obj1'
  , ative: true
  , children: 
    [ { name: 'obj2'
      , ative: true
      , children: 
        [ { name: 'Obj23'
          , ative: true
          , children: [...] 
      } ] } 
    , { name: 'obj3'
      , children: 
        [ { name: 'Obj32'
          , ative: true
          , children: [...] 
      } ] } 
    , ...
    } 

My goal is to set the active property to false for the main object obj1 and all its children, including sub-children.
I am unsure of how many levels of children there might be under each child, so I believe a loop using something like map will be necessary.
The loop should terminate when a child has no further children (length equals 0).

UPDATE: I appreciate all the helpful solutions provided. Thank you!

Answer №1

To achieve the same outcome, you can utilize JSON.parse along with reviver function like so:

JSON.parse(JSON.stringify(obj), (key, value ) => key === 'ative' ? false : value );

const obj = {
    name: 'object1',
    ative: true,
    children: [{
        name: 'object2',
        ative: true,
        children: [{
            name: 'Object23',
            ative: true,
            children: []
        }]
    },
    {
        name: 'object3',
        children: [{
            name: 'Object32',
            ative: true,
            children: []
        }]
    }]
}

const result = JSON.parse(JSON.stringify(obj), (key, value) => key === 'ative' ? false : value);

console.log(result);

Answer №2

There are two primary methods that can be employed

  1. Sequential method
  2. Recursive technique

Typically, the sequential method proves to be more efficient in terms of both memory usage and processing speed compared to the recursive approach, which necessitates extra memory complexity of O(n) for each function call in the stack.

In the sequential method, utilizing array functions such as map and forEach becomes impractical due to the uncertainty of the array length and termination criteria. Even if applied, it would involve modifying the traversed array, leading to unintended side effects. Instead, a basic while loop will suffice.

Procedure:

  • Form a stack array and insert the initial object into it
  • While the stack is not empty
    • Select the current item popped from the stack
    • Assign false to current's active
    • Include the children of current into the stack to explore their descendants
  • Provide the resulting item (optional, considering the modification of the original object)

Code Structure:

Firstly, define a schema for the input data structure:

type Element = {
  title: string;
  active?: boolean;
  children: Element[];
};

Next, implement the main function:

const activateItems = (data: Element): Element => {
  const stack = [data];

  while (stack.length) {
    const current = stack.pop();

    if (!current) continue;

    current.active = false;

    stack.push(...current.children);
  }

  return data;
};

sandbox

Answer №3

While wonderflame makes a valid point about the advantages of a stack-based approach for unknown tree sizes, it's important to consider that if you are confident your tree will not grow too deep, a recursive method may be more straightforward and practical.

def deactivate_recursive(obj):
  
  return {
    ...obj,
    active: False,
    children: [deactivate_recursive(child) for child in obj.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

What is the recommended method for deleting sequelize.connectionManager.getConnection according to the Sequelize documentation?

I am currently developing an AWS Lambda function using Typescript that interacts with a database through Sequelize. According to the official Sequelize documentation, the configuration for Sequelize should be as follows: let sequelize = null; async func ...

Tips for choosing or moving to an iframe

What is the best method for choosing or transitioning to an Iframe (as the currently targeted document) using Selenium webdriver in Firefox? Are there alternative approaches for selecting an iframe with or without webdriver? driver.switchTo.frame("Frame ...

Is there a way to retrieve the timestamp of a DOM change event when using MutationObserver for event tracking?

Currently, I am successfully using MutationObserver to monitor changes in the DOM. However, I would like to include a timestamp for each event. Unfortunately, there doesn't seem to be a timestamp property available in the MutationRecord. https://deve ...

The issue with sorting in Angular 8 mat tables persists when dealing with multiple tables

As a newcomer to Angular, I am still learning and have encountered an issue with sorting in the mat table. I have multiple tables on one page, each separated by a mat tab. The problem is that sorting only works on the first table ("crane master list") in t ...

Node is currently posing a challenge for the installation of packages

I am currently facing an issue while setting up my raspberry pi 3. I am attempting to install and execute a node code, but I encountered a problem during the installation of packages using npm. After trying multiple times with different versions of node ( ...

Manipulate elements by adding and removing classes sequentially based on an array

Previously, some had difficulty understanding my question. I have an array of variables representing the ids of 5 divs. My goal is to change the color of each div sequentially for a brief moment before reverting back, mimicking the behavior of traffic ligh ...

Integrating concealed elements into jspdf

I am currently working on incorporating a hidden div into my jspdf file. Utilizing html2canvas for this purpose, I find it necessary to briefly make the div visible, add it to the pdf, and then hide it again. This method is not ideal as the content moment ...

Function to save prices as cent-based figures in Javascript using Regex

Trying to extract prices from a string using regex can be tricky, as unexpected issues may arise. For example, obtaining the following values: US$1234.56 $12 $12.34usd $0.56 .56 dollars and converting them to: 123456 1200 1234 56 56 is necessary for s ...

Ways to turn off a TypeScript error across the entire project

Due to an unresolved TypeScript bug causing a false positive, I am looking to disable a specific TypeScript error for my entire project. How can this be achieved? The requirements are: Disabling only one type of error Not limited to a single line or file ...

Spinning divs using JavaScript when the mouse hovers over them, and then returning them to their original position when the mouse moves

I am looking to create a functionality where a div rotates when the mouse enters it and returns to its original position when the mouse leaves. Everything works fine when interacting with one div, but as soon as I try hovering over other divs, it starts gl ...

What is the best way to shrink or enlarge individual sections of the accordion?

Exploring AngularJs Accordions I'm struggling to understand how to control accordions in AngularJS. I have a step-by-step module set up as an accordion and I want to collapse one part while expanding another based on completion. Here is the accordion ...

What is the best way to create a dynamic information page using both V-for and V-if in Vue.js?

Hey everyone, I recently attempted to set up this layout: This company offers a variety of services grouped into different categories, each containing sub-options and specific details. This is how my JSON data is structured: { "services& ...

Issue with setting and showing the PHP data array within the vue.js variable

I am encountering an issue with transferring an array of data from a PHP session variable to a Vue.js variable Here is how I am trying to assign an array of data to a Vue.js variable: permissions:['<?php echo json_encode($_SESSION['permission ...

Instructions on how to eliminate the minutes button from Material UI datetime picker

I'm currently working on customizing a datetimepicker from materialUI in ReactJS. My goal is to prevent the user from seeing or selecting minutes in the picker interface. Despite setting the views prop to include only year, month, date, and hours, use ...

Verifying user input with JQuery's $.post function

I have a question regarding asynchronous calls. My goal is to validate whether a given "code" is valid without refreshing the page. Here's the scenario in brief: I need to determine if a variable should be set to true or false based on the response ...

TypeORM issue - UnsupportedDataTypeError

Here is the entity file I'm working with, user.ts: @Entity('users') export class User { @PrimaryGeneratedColumn() id: number | undefined; @Column({ type: 'string', name: 'username', nullable: true }) username: s ...

Troubleshooting Ajax contact form's failure to refresh (PHP and Bootstrap 4)

I have successfully implemented this code on one website, but it is not working as expected on another website. It sends the email but refreshes the page and redirects to a contact.php page with a message. Despite double-checking everything, including cha ...

Using PHP to calculate the total number of records within an HTML document

I am currently working on a PHP script to establish a connection with my MySQL database in order to retrieve the total number of users registered on my forum by counting the records in the table. https://i.sstatic.net/ZR0IY.png The PHP script should disp ...

Issue with Material-ui IconButton's edge properties not functioning as expected

Is there a way to position the delete icon on the right side of the screen? It seems like using edge= "end" is not working as expected. If you'd like to take a look, here is the sandbox link: https://codesandbox.io/s/admiring-silence-vwfoe? ...

Tips for maximizing the benefits of debounce/throttle and having a truly dynamic experience

Attempting to implement a similar concept in Vue: props(){ debouncing: {type: Number, default: 0} }, methods: { clicked: _.debounce(function() { this.$emit('click'); }, this.debouncing), } Unfortunately, the code breaks when ...