Extract elements from the nested object's virtuals and add them to the main object array

I have an array of objects with nested arrays, all with a similar structure. I want to flatten the array so that all objects are on the same level.

[
  {
   "name": "United States",
   "slug": "united-states",
   "states":[
     {
      "name": "Arizona",
      "slug": "arizona"
     },
     {
      "name": "California",
      "slug": "california"
     }
    ]
  },
  {
   "name": "Canada",
   "slug": "canada",
  }

]

The resulting flattened array should look like this:

[
  {
   "name": "United States",
   "slug": "united-states"
  },
  {
   "name": "Arizona",
   "slug": "arizona"
  },
  {
   "name": "California",
   "slug": "california"
  },
  {
   "name": "Canada",
   "slug": "canada",
  }

]

Answer №1

By leveraging the power of Array#flatMap:

const data = [
  {
    "name": "United States",
    "slug": "united-states",
    "states":[
      { "name": "Arizona", "slug": "arizona" },
      { "name": "California", "slug": "california" }
    ]
  },
  { "name": "Canada", "slug": "canada" }
];

const res = data.flatMap(({ name, slug, states = [] }) => ([
  { name, slug },
  ...states
]));

console.log(res);

Answer №2

If you want to efficiently navigate through a tree structure, one approach is to create an iterator specifically for that purpose and then convert it into an array. This method is effective even for deeply nested trees and doesn't require knowledge of which property holds the child nodes. It assumes that the property containing an Array value represents the subtrees:

function * traverse(forest) {
    for (const item of forest) {
        const arrayKey = Object.entries(item).find(([k, v]) => Array.isArray(v))?.[0];
        const { [arrayKey]: children, ...rest } = item;
        yield rest;
        if (children) yield * traverse(children);
    }
}

const data = [{"name": "United States","slug": "united-states","states":[{ "name": "Arizona", "slug": "arizona" },{ "name": "California", "slug": "california" }]},{ "name": "Canada", "slug": "canada" }];

const res = [...traverse(data)];

console.log(res);

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

Issue with showing second page in form post using Express.js: node.js, express.js and jade

I am a beginner in node and express and I created a small app, but it's not functioning properly. When I submit a post on page 1, the app does not display page 2. Here is the structure and code of my project: / /controller/controllers.js /node_module ...

Mongoose Error: Incompatible receiver called Method Uint8Array.length

I am currently working on a small website that incorporates i18n. Initially, I used local json files, but upon transitioning to mongodb, I encountered an unfamiliar error. Any detailed explanation of this issue would be greatly appreciated. The specific e ...

Multiple individual image uploads via ajax on a single webpage

Currently, I am facing an issue with my ajax upload script. It only allows for one image upload at a time which is causing problems for me as I am working on a shop CMS that requires multiple image uploads for each product. Each product needs a thumbnail i ...

Delete any classes that start with a specific prefix

Within my code, there is a div that holds an id="a". Attached to this div are multiple classes from different groups, each with a unique prefix. I am uncertain about which specific class from the group is applied to the div in JavaScript. My goal is to r ...

When the page is refreshed, the JWT token mysteriously disappears from the header. How can this issue be resolved

I am currently using Jwt token based authentication with Angular 7 and node.js. When attempting to send a POST request with a Token to the server, everything works fine initially. However, upon reloading the page, I encounter an error on the server side. ...

Using JavaScript to parse JSON data containing additional curly braces

Looking at this JSON object: var dataObj = { data: '\n{ sizeMap:{\nxSizes: "REGULAR|SMALL", \ncurrItemId: "",\ncurrItemSize: "",\nmanufacturerName:"Rapid",\npartNumber: "726G", \nsuitStyle: "R",\nhasSC: "",&bso ...

The method is called after the focus is removed from the element

Currently, I am working on a project involving textboxes arranged in a grid to represent each day of the week. Alongside these textboxes is a drop-down list displaying the dates for that week, as well as a text area designated for specific comments related ...

"An error occurred with the Ajax post request - bad request

I've encountered a strange issue while attempting to make a POST request using AJAX with the code snippet below: $('.login-form').on('submit', function(e) { e.preventDefault(); $.ajax({ type: "post", url: " ...

JavaScript allows you to create matrices from squares

Hey everyone, I'm facing an issue with creating matrices in HTML. I need to display a 5x5 matrix where each index is represented by a square. I tried using a span template for the box and then wrote a script to populate the matrices, but it's no ...

" Jquery.ajax, PHP, and the case of the mysteriously missing response

I've been struggling to create my first universal code for handling ajax responses. Unfortunately, I haven't been able to see any output either in PHP or in the ajax response. There must be something missing in the post data. Below is the ajax r ...

Tips for preventing multiple links from opening when clicking the same link

Having a data grid with a hyperlink control that allows users to open a new tab displaying selected item information poses the issue of multiple tabs opening when the same item is clicked multiple times. Is there a way to have the tab open only the first t ...

Refreshing the DeckGL HexagonLayer upon changes to the data array/Initiating a reload for the DeckGL HexagonLayer

I am currently using DeckGL along with React to showcase data on an OpenStreetMap. My goal is to incorporate filters to allow for different views of the data I possess. The main issue I encounter is the inability to refresh the layer representing the data ...

Incorporate a delay when using jQuery's mouseenter function

I'm trying to implement a tooltip that appears 5 seconds after the mouse enters. Here's the code I've been working with: $('thead').mouseenter( function() { var tooltip = $('<div id="tooltip" class="tooltip-container ...

The $(document).ready function may not be compatible with Internet Explorer

I have a page with two links - one for registering and one for logging in. Currently, the register link is the most important. When clicked, it loads a .tpl file using jQuery's load function. Within this tpl file, I include a new JavaScript file usin ...

Utilizing @casl/vue in conjunction with pinia: A guide to integrating these

I'm currently facing an issue with integrating @casl/ability and Vue 3 with Pinia. I'm unsure of how to make it work seamlessly. Here is a snippet from my app.js: import { createApp } from "vue" const app = createApp({}) // pinetree i ...

Updating AngularJS views based on window resizing

I've been working on an Angularjs application and everything is running smoothly, but I'm facing challenges when it comes to implementing a mobile version of the site. Simply using responsive styles won't cut it; I need to use different view ...

The Vuetify navigation drawer seems to have a quirk where it only closes after an item

I am brand new to Vue and struggling to figure out why my vue v-navigation-drawer is not working properly. It is located in app-root.vue and was initially closing when clicking on a drawer item, but now requires two clicks to close. After the first click, ...

The dynamic duo of web development: React and Bootstrap JavaScript

As I work with ReactJS, I have come to understand that using JQuery or vanilla JS to directly manipulate the DOM is not recommended. This is because ReactJS operates using a virtual DOM, which can lead to unpredictable outcomes. My question now is: if I w ...

When using `element.addEventListener`, event.target will be the target

When working on a solution, I initially bound event listeners to multiple targets within the same container. I am curious to know if anyone has noticed considerable performance improvements by using just one event listener and leveraging the target of the ...

Retrieving a single value from the response entity JSON data

I am in need of connecting to a rest service in order to retrieve the user id using a token. List<Object> providers = new ArrayList<>(); providers.add(new JacksonJaxbJsonProvider()); client = WebClient.create(properties.getProperty(URL), prov ...