How to Unravel Deeply Nested Objects and Arrays in JavaScript

As a newcomer to JavaScript, I am facing the challenge of flattening nested objects and arrays in my code.

One of the complex structures I have to work with is:

[{ a: 2, b: [{ c: 3, d: [{e: 4, f: 5}, {e: 5,f: 6}]}, 
                 { c: 4, d: [{e: 7, f: 8}]}
                ]
    }]
    

and my desired output would be:

[{a:2,c:3,e:4,f:5}, {a:2,c:3,e:5,f:6}, {a:2,c:4,e:7,f:8}]
    

Although I attempted to modify an existing function for objects to work with arrays, I am only able to flatten the final object within the array [{a:2,c:4,e:7,f:8}]. I believe the challenge lies in iterating through arrays and objects effectively.

Here is the original script I tried to adapt:

function flatten(obj) {
        var flattenedObj = {};
        Object.keys(obj).forEach(function(key){
            if (typeof obj[key] === 'object') {
                $.extend(flattenedObj, flatten(obj[key]));
            } else {
                flattenedObj[key] = obj[key];
            }
        });
        return flattenedObj;    
    }
    

These are my modified scripts (yielding the same result for both):

flat_array=[];
    function superflat(array){
       for (var i = 0; i < array.length; i++) {
           var obj = array[i]
           var flattenedObj = {};
           Object.keys(obj).forEach(function(key){
              if (typeof obj[key] === 'object') {
                 $.extend(flattenedObj, flatten(obj[key]));
              } else {
                 flattenedObj[key] = obj[key];
              }
           });
           flat_array.push(flattenedObj);
        }
    };
    
mega_flat_array=[];
    function megaflatten(obj) {
         Object.keys(obj).forEach(function(key){
         var flattenedObj = {};
            if (typeof obj[key] === 'object') {
                $.extend(flattenedObj, flatten(obj[key]));
            } else {
                flattenedObj[key] = obj[key];
            }
         mega_flat_array.push(flattenedObj);
         });
    }
    

Thank you in advance for any assistance you can provide.

Answer №1

I recommend starting with simple data objects to test your function, then gradually introduce more complex objects until the function performs as desired. Use forEach to iterate through the objects.

Start with a basic test1 object, then progress to test2 and so on, breaking down the logic into smaller steps.

To eliminate previous duplicates, I utilized error handling by throwing and catching errors to exit the recursive forEach loops. This prevented unnecessary duplicate "rows". Consider using a standard for loop for better control and error handling.

The recursive function checks the type of object (array or object) and iterates through them to append values. If the type is neither an array nor an object, the function is called again. If a duplicate key is encountered, such as { c: 3 }, the current key is removed and the new one is added before continuing the loop.

If you have additional sample data, you can add more tests. However, there are specialized libraries available to assist with Test-Driven Development (TDD).



// Your customized code can go here

Answer №2

While it may be quite large and doesn't maintain the original order of keys, this solution successfully handles duplicates.

Keep in mind that it uses recursion, so be cautious of the call stack.

  • To begin, iterate through the items in the array.
  • If an item is an array, a recursive call is made.
    • Upon returning from the call, if there are more objects returned than currently in the final result, the returned objects are updated with properties from the final result objects, ensuring not to overwrite existing properties.
    • Otherwise, update the final results with properties from the returned result, again being mindful not to overwrite existing properties.
  • If the item is not an array:
    • If it's the first item, place it in the final result.
    • Otherwise, add the item's properties to all items in the final result without overwriting any.

function createFlatArray(arr) //always assumed you pass in an array
{
  let objects = [];
  arr.forEach(item =>
  {
    let currentObject = {};
    const keys = Object.keys(item);
    keys.forEach(key =>
    {
      const obj = item[key];
      if(Array.isArray(obj))
      {
        let parts = createFlatArray(obj);
        if(objects.length > 0)
        {          
          if(parts.length > objects.length)
          {
            parts.forEach(part =>
            {
              objects.forEach(ob =>
              {
                Object.keys(ob).forEach(k =>
                {
                  if(Object.keys(part).indexOf(k) == -1)
                  {
                    part[k] = ob[k];
                  }
                });
              });
            });
            objects = parts;
          }
          else
          {
            objects.forEach(ob =>
            {
              parts.forEach(part =>
              {
                Object.keys(part).forEach(k =>
                {
                  if(Object.keys(ob).indexOf(k) == -1)
                  {
                    ob[k] = part[k];
                  }
                });
              });
            });
          }
        }
        else
        {
          objects = parts;
        }
      }
      else
      {
        if(Object.keys(currentObject).length == 0)
        {
          objects.push(currentObject);
        }
        currentObject[key] = item[key];
        
        objects.forEach(ob =>
        {
          if(Object.keys(ob).indexOf(key) == -1)
          {
            ob[key] = currentObject[key]
          }
        });
      }
    });
  });
  return objects;
}

const input = [{ a: 2, b: [{ c: 3, d: [{e: 4, f: 5}, {e: 5,f: 6}]}, 
                         { c: 4, d: [{e: 7, f: 8}]}
            ], g:9
}];

let flattened = createFlatArray(input);

flattened.forEach(item => console.log(JSON.stringify(item)));

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 React application is failing to build and is displaying the error code ELIFECYCLE

Having trouble with this error that keeps popping up every time I attempt to build the project. Can anyone provide assistance? Error code ELIFECYCLE Error number 1 Error in [email protected] build: react-scripts build Exit status 1 Failed at the [ema ...

Extracting data from large Arrays in PHP

In my script, I store player data in an array that changes based on the number of players present. The structure of the array is as follows: Array ( [0] => Array ( [Id] => 0 [Name] => Playername1 [Fr ...

Building an HTML table dynamically with JavaScript

Can anyone help me figure out why my JavaScript code isn't populating the HTML body table as expected? var shepard = { name: "Commander", victories: 3, ties: 1, defeats: 6, points: 0 }; var lara = { name: "RaiderOfTombs", victories: ...

Tips for displaying 2-dimensional arrays using a function in C++

I've been working on creating a function to display two-dimensional arrays after successfully implementing one for one-dimensional arrays. #include <iostream> using namespace std; void printArray(int theArray[], int sizeOfArray); int main() { ...

What is the process for deselecting a checkbox?

I am facing a situation where I need to uncheck a checkbox that is always checked based on user input from another section of my form. Specifically, I have implemented an onChange="functionName" event on a select box. Can someone guide me on how to accom ...

Is there a simpler way to retrieve data from PHP or to efficiently filter the data once it's been retrieved?

Creating a business directory website involves fetching data from a database. The issue arose when attempting to apply a function uniformly to all boxes, as only the first one with the specified id would function correctly. To address this problem, the fol ...

"Enhance your Angular experience with SweetAlert integration using directives and translation

Currently, I am utilizing the Angular implementation of the SweetAlert plugin from GitHub. I am attempting to pass an Angular directive with translation to the title. The variable being passed as the title is: {{ 'register.confirmation_modal.SUPERI ...

Exploring Angular 10: Managing Two Promises in ngOnInit

I am currently working on integrating the Strava API into my Angular app. To summarize briefly: When a user clicks on a button to connect to Strava They are redirected to Strava for authentication (using PKCE) Strava then redirects back to my app with a ...

Closure-compiler and its peculiar pre-codeyntax

When it comes to minimizing my JS code, I typically rely on the online closure compiler available at . Recently, I've been attempting to incorporate this process into PhpStorm using "External tools," but I seem to be encountering a strange issue. Ever ...

Retrieving and storing data using jQuery's AJAX caching feature

When utilizing jQuery's $.ajax() method to perform an XHR based HTTP GET request to obtain a partial of HTML from a Ruby on Rails website, I encounter an issue. Specifically, every time a user clicks on tabbed navigation, I refresh an HTML table with ...

Angularjs: a powerful tool for passing data efficiently between controllers

In my angular.js application, I have implemented multiple views and I am in need of maintaining the status across view changes. To achieve this, I have created a simple factory to share data between controllers. Instead of using "$scope" in the controllers ...

Distribute the capabilities of the class

Is there a way to transfer the functionalities of a class into another object? Let's consider this example: class FooBar { private service: MyService; constructor(svc: MyService) { this.service = svc; } public foo(): string { ...

Issue: React child must be a valid object - Runtime Error Detected

As I delve into the world of React, NextJs, and TypeScript, I stumbled upon a tutorial on creating a navbar inspired by the 'Strip' style menu. It has been quite a learning journey for me as a newbie in these technologies. After seeking help for ...

Using code, you can implement this by utilizing the following URL: https://graph.facebook.com/ql?q=http://google.com

(PLEASE AVOID CLICKING NEGATIVE RATINGS. I REALLY NEED AN ANSWER TO THIS. THANK YOU) As a beginner in coding and learning, I am eager to edit the code on my website. The code/link https://graph.facebook.com/fql?q=http://google.com has already been depreca ...

Clicking on a card will cause it to expand

Exploring Material-UI-React for the first time to create expanding cards, I've encountered an issue where all cards expand when one is clicked. How can I modify my code so that only the clicked card expands without affecting the others? const useSt ...

What is the method for incorporating functionality into the "X" icon within the Material UI Searchbar?

Check out this code snippet: import SearchBar from "material-ui-search-bar"; const info = [ { name: "Jane" }, { name: "Mark" }, { name: "Jason" } ]; export default function App() { const [o ...

How to locate the index.js file within my application using Node.js?

Directory Structure bin - main.js lib - javascript files... models - javascript files... node_modules - folders and files public - index.html route - javascript files... index.js package.json I am using Express and angular.js. The ser ...

Guide on displaying a list of images in a single line with rows and columns

I am in search of a solution to create the user interface depicted in the attached image using React. Additionally, this post includes a link to another post on the same site: How to add a single line image list that is horizontal scrollable (in react js). ...

Checking for duplicate entries in an array created with the Angular form builder

I am currently utilizing angular6 reactive form with form builder and form array. The issue I am encountering is duplicate subject entries from the drop down in the form array. How can I implement validation to prevent duplicate entries in the form array? ...

Using Sequelize to update all values in a JSON file through an Express router.put operation

I've been working on a feature in my Express router that updates data in a MySQL schema for 'members' of clubs. The members table has various columns like member_id, forename, surname, address, etc. I've successfully created an Express ...