How can you "flatten" an array containing objects?

What is the most efficient method to "flatten" a JSON array of objects using only JavaScript or Lodash?

Consider this sample array

[
  {
  "name": "Mat",
  "age": "18",
  "studies": [
      {
        "subject": "English",
         "mark": 5
      },
      {
        "subject": "Maths",
         "mark": 4
      }
    ],
  },
  {
  "name": "Alice",
  "age": 20,
  "city": "New York"
  }
]

Desired output:

[
  {
   "name": "Mat",
   "age": "18",
   "subject": "English",
   "mark": 5
  },
  {
   "name": "Mat",
   "age": "18",
   "subject": "Maths",
   "mark": 4
  },
  {
   "name": "Alice",
   "age": 20,
   "city": "New York"
  }
]

Here's an edited working code snippet:

rows.forEach(row => {
    let newRow = {}

    _.forOwn(row, (value, key) => {
            value.forEach(item => {
              _.forOwn(item, (value, key) => {
                 newRow[key] = value
               })
            })

           } else {
             newRow[key] = value
           }
      })
  })

The current code doesn't include first-level properties like name, which was sufficient for previous requirements. However, now all properties except those under fields like studies are needed.

Answer №1

Here is a modern approach to achieving this:

var d = [{"name":"Mat","age":"18","studies":[{"subject":"English","mark":5},{"subject":"Maths","mark":4}]},{"name":"Alice","age":20,"city":"New York"}];

var r = d.reduce((a, {studies, ...rest}) =>
  [...a, ...(studies || [{}]).map(s => ({...s, ...rest}))]
, []); 

console.log(r);

Keep in mind that browser support for this syntax may be limited, consider using a transpiler if necessary.


This method utilizes the new rest syntax for object literals within the second parameter of the .reduce() callback. This separates the studies array into its own variable and assigns all other properties to the rest object.

The spread syntax then combines the current accumulator array members with mappings of the new objects from studies within the callback result.

Within the .map() callback function, the object literal spread syntax is used to merge the properties of the rest object from the .reduce() callback and the properties of the current "study" object into a new object literal which is returned.

If there are no studies, an empty array with an empty object is substituted to ensure it retains the rest properties.


If the key for flattening is dynamic, there is still a way to achieve it, albeit slightly longer.

var d = [{"name":"Mat","age":"18","studies":[{"subject":"English","mark":5},{"subject":"Maths","mark":4}]},{"name":"Alice","age":20,"city":"New York"}];

function flatten(key, data) {
  return data.reduce((a, user) => {
    const arr = user[key];
    delete user[key];
    return [...a, ...(arr || [{}]).map(s => ({...s, ...user}))]
  }, []);
}

console.log(flatten("studies", d));

If the destructuring syntax allowed square bracket expression evaluation like this {[key], ...user}, it would simplify the code, but unfortunately, that is not currently supported.

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

Error: SyntaxError encountered - JSON input unexpectedly ended

Below is a script that handles AJAX requests: var ajax = new XMLHttpRequest(); ajax.onreadystatechange = function() { if (JSON.parse(ajax.responseText).result == 'error') { console.log('error') $.each(JSON.parse(aja ...

Highcharts facing issues with data rendering

This is the JSON data I have: [ { "project_title":"sdsdsd", "project_ref_id":"112", "amount":"232323.00", "months":"Mar-2015" },{ "project_title":"test project 44", "project_ref_id":"113", "a ...

Unable to change a string to an integer - Retrieving values from a nested Hash

While I've come across several similar topics, it seems like I'm still missing a crucial piece. <. The main goal here is to define a variable named $db_url that holds the database credentials, host address, and name. However, when attempting ...

Getting the value of a data attribute using jQuery

Is there a way to retrieve the value of the userid data attribute from an HTML table and store it in a variable without requiring a click action? <table id="tblList"> <tbody id="someTest"> <tr data-userid="801992084067"> ...

Encountering SCRIPT1014 and SCRIPT1002 errors within an Angular4 application when using Internet Explorer 11

My Angular 4 application runs perfectly in various browsers. However, when trying to launch it in Internet Explorer version 11, I encounter the following two errors: SCRIPT1014: Invalid character addScript.js (9,1) SCRIPT1002: Syntax error main.bundle.js ...

What is the best way to apply multiple text shadows to a single piece of text using the jQuery ".css()" method?

Is it possible to create multiple text shadows for a single piece of text using the jQuery ".css()" method? I'm currently working on animating the title of a page on my website, which includes adding a 3D effect with multiple shadows. I also want to ...

Set the camera to view the world from a y-coordinate of 0 and descend

How can I make the top of the render area in Three.js point to y=0 in the world? I also want the camera to look straight (lookAt) These are my current values: camera = PerspectiveCamera camera.position.z = 1895.8448868133867 camera.fov = 20 screen.width ...

Execute a function on a canvas timer using the setTimeout method

I'm having an issue with my setTimeout function in this code. I want it to call a timer function for a delay, but it's not working consistently every second. Why is that happening? <head> <script> function timer(sec) { var c = do ...

Explanation on JSON files

I am currently working on a basic mock eCommerce website project that does not require a connection to a database. I have heard about using JSON files as a database alternative for a small-scale application. Each JSON file would have various fields, includ ...

Adapting Cube Sizes on the Fly Using AngularJS

Trying to create a dynamic cube in Three.js that can be modified based on user input. The connection is established using angular.js: This snippet of HTML code enables users to input and adjust the values: <body> <div id="mainContainer"> ...

Angular Commandments: Understanding the Directives

Within my code, there is a specific directive view that I am utilizing: <div class="busy-indicator angular-animate" ng-show="busy"></div> <div class="breadcrumblist" ng-class="atTopLevel ? ['at-top-level'] : null"> <div ...

Dealing with errors in an AJAX $get request using an anonymous function can be managed by following these steps

I am looking to create an AJAX function similar to the following: $.get("./v1/user/"+username, function(response) { document.getElementById("username").innerHTML=response.username; }); In case of failure, I want to modify the style property of a diff ...

Guide on displaying JSON information upon clicking using JavaScript

I'm having difficulty writing the logic for this code. I have extracted data from a vast API. The current code fetches all program titles (some may be repeated) and compares them with an array of late night shows, then displays them once in their own ...

Export JSON data to a CSV file using Java programming

I'm having trouble figuring out how to send files back to the client using Java. Specifically, I want to create a CSV file that can be opened in Excel. After discovering this tool for server-side creation of CSV files, I'm unsure of the process ...

Angular's mat table paginator now efficiently loads all data directly onto the first page

Currently, I am facing an issue while loading JSON data from a backend ASP.NET Core C# API to an Angular material table. The problem lies in the fact that all 100 rows of JSON data are being loaded onto the first page, despite setting up the paginator with ...

Converting a sub struct into a string and then back again

I've encountered an issue with the UnmarshalJSON and MarshalJSON functions that I'm struggling to understand or locate the error after hours of searching. I have the following User struct: type User struct { ID uuid.UUID `go ...

Generating validation errors along with line numbers

When I map a JSON string to a POJO, it works smoothly. The POJO constructor includes some validation constraints (such as requiring an integer property to be positive) and throws an IllegalArgumentException when these constraints are not met. I would like ...

Learn how to use an Angular Directive to automatically set the default value within an HTML Text box element. The code snippet provided below will guide you

I have encountered an issue with the code below. It seems to be working fine for changing the innerHTML of div and heading tags, but I am facing difficulties when trying to apply it to textboxes. @Component({ selector: 'app-root', template: ...

In the world of Node.js and Java, the concepts of "if"

Here is a code snippet that I am working with: var randFriend = friendList[Math.floor(Math.random() * friendList.length)]; if (randFriend == admin) { //Do something here } else if (randFriend != admin) { client.removeFriend(randFriend); } I am tr ...

Struggling with a 404 error when using Backbone's fetch method

I am currently facing a 404 error while attempting to use this backbone model node to fetch data from the server. Despite verifying that my files are correct, the issue persists var app = app || {}; app.NotesModel = Backbone.Model.extend({ url:' ...