What is the best way to generate an array by extracting items from various nested values?

The structure of the array I'm working with is as follows (with variable objects inside):

this.selected_sum_version may contain multiple groups:

this.selected_sum_version.sum_item_groups = [
    {
        "id": 1,
        "name": "GROUP 1",
        "version_id": 1,
        "sum_items": [
            {
                "id": 1,
                "type": "formula",
                "sum_item_group_id": 1,
                "formula": {
                    "id": 1,
                    "name": "Formula NAME",
                    "sum_item_id": 1
                },
                ...
            },
            ...
        ]
    },
    ...
]

Each object within this.selected_sum_version.sum_item_groups has a 'type' which can be grid, chart, formula, or text_box.

I need to generate a new array, starting with newArray = [], containing all names based on the type. For example, using the data above, newArray would be:

this.newArray = ['Formula NAME', 'Wei', 'Lan', 'JFM', 'JC'].

Based on the 'type' field in each object, one of 'formula, text_box, grid, or chart' will not be null and will have an id, name, and sum_item_id. The goal is to create newArray with all those names.

The current code provided below accomplishes the task but there might be a more efficient and cleaner way to write it. Any suggestions?

var emptyArray = [];

this.selected_sum_version.sum_item_groups.forEach(element => {
        element.sum_items.forEach(elementtwo => {
            if (elementtwo.type === 'formula') {
                newArray.push(elementtwo.formula.name);
            } else if(elementtwo.type === 'grid') {
                newArray.push(elementtwo.grid.name);
            } else if(elementtwo.type === 'chart') {
                newArray.push(elementtwo.chart.name);
            } else if(elementtwo.type === 'text_box') {
                newArray.push(elementtwo.text_box.name);
            } 
        });
});

Answer №1

While I haven't personally run this code snippet, it appears that you may be able to access the value within type directly without needing to check its value beforehand.

this.selected_sum_version.sum_item_group.forEach(group => {
        group.sum_items.forEach(item => {
                updatedArray.push(item[item.type].name);
        });
});

Answer №2

Your approach may not result in a more efficient solution, but it does offer improved code readability.

let emptyArray = [];
const dataTypes = new Set(['formula', 'grid', 'chart', 'text_box']);

this.selected_sum_version.sum_item_group.forEach(item => {
  elementtwo.sum_items.forEach(subItem => {
    if (dataTypes.has(subItem.type)) {
      newArray.push(subItem[subItem.type].name);
    }
  }
}

Note: The assumption here is that there are specific types you want to exclude from the array. If all names should be added regardless of type, then the set check might not be necessary.

Answer №3

This method demonstrates an efficient approach using reduce, map, the Nullish coalescing operator, and optional chaining

const result = sum_item_groups.map(({ sum_items }) =>
  sum_items.map(
    (obj) =>
      obj.formula?.name ??
      obj.text_box?.name ??
      obj.grid?.name ??
      obj.chart?.name
  )
);

console.log(result.flat());

const sum_item_groups = [
  {
    id: 1,
    name: "GROUP 1",
    version_id: 1,
    sum_items: [
      {
        id: 1,
        type: "formula",
        sum_item_group_id: 1,
        formula: {
          id: 1,
          name: "Formula NAME",
          sum_item_id: 1,
        },
        summary_text_box: null,
        grid: null,
        chart: null,
      },
      {
        id: 4,
        order: 2,
        type: "text_box",
        sum_item_group_id: 1,
        formula: null,
        text_box: {
          id: 1,
          name: "Wei",
          sum_item_id: 4,
        },
        grid: null,
        chart: null,
      },
      {
        id: 5,
        order: 3,
        type: "text_box",
        sum_item_group_id: 1,
        formula: null,
        text_box: {
          id: 2,
          name: "Lan",
          sum_item_id: 5,
        },
        grid: null,
        chart: null,
      },
    ],
  },
  {
    id: 4,
    name: "GROUP 2",
    version_id: 1,
    sum_items: [
      {
        id: 7,
        order: 1,
        type: "text_box",
        sum_item_group_id: 4,
        formula: null,
        text_box: {
          id: 4,
          name: "JFM",
          sum_item_id: 7,
        },
        grid: null,
        chart: null,
      },
    ],
  },
  {
    id: 5,
    name: "GROUP 3",
    version_id: 1,
    order: 3,
    sum_items: [
      {
        id: 6,
        order: 1,
        type: "text_box",
        sum_item_group_id: 5,
        formula: null,
        text_box: {
          id: 3,
          name: "JC",
          sum_item_id: 6,
        },
        grid: null,
        chart: null,
      },
    ],
  },
];

const result = sum_item_groups.map(({ sum_items }) =>
  sum_items.map(
    (obj) =>
      obj.formula?.name ??
      obj.text_box?.name ??
      obj.grid?.name ??
      obj.chart?.name
  )
);

console.log(result.flat());

or

const result = sum_item_groups.reduce((acc, { sum_items }) => {
  const values = sum_items.map((obj) => {
    return ( obj.formula?.name ?? obj.text_box?.name ?? obj.grid?.name ?? obj.chart?.name);
  });
  return [...acc, ...values];
}, []);

console.log(result);

const sum_item_groups = [
  {
    id: 1,
    name: "GROUP 1",
    version_id: 1,
    sum_items: [
      {
        id: 1,
        type: "formula",
        sum_item_group_id: 1,
        formula: {
          id: 1,
          name: "Formula NAME",
          sum_item_id: 1,
        },
        summary_text_box: null,
        grid: null,
        chart: null,
      },
      {
        id: 4,
        order: 2,
        type: "text_box",
        sum_item_group_id: 1,
        formula: null,
        text_box: {
          id: 1,
          name: "Wei",
          sum_item_id: 4,
        },
        grid: null,
        chart: null,
      },
      {
        id: 5,
        order: 3,
        type: "text_box",
        sum_item_group_id: 1,
        formula: null,
        text_box: {
          id: 2,
          name: "Lan",
          sum_item_id: 5,
        },
        grid: null,
        chart: null,
      },
    ],
  },
  {
    id: 4,
    name: "GROUP 2",
    version_id: 1,
    sum_items: [
      {
        id: 7,
        order: 1,
        type: "text_box",
        sum_item_group_id: 4,
        formula: null,
        text_box: {
          id: 4,
          name: "JFM",
          sum_item_id: 7,
        },
        grid: null,
        chart: null,
      },
    ],
  },
  {
    id: 5,
    name: "GROUP 3",
    version_id: 1,
    order: 3,
    sum_items: [
      {
        id: 6,
        order: 1,
        type: "text_box",
        sum_item_group_id: 5,
        formula: null,
        text_box: {
          id: 3,
          name: "JC",
          sum_item_id: 6,
        },
        grid: null,
        chart: null,
      },
    ],
  },
];

const result = sum_item_groups.reduce((acc, { sum_items }) => {
  const values = sum_items.map((obj) => {
    return ( obj.formula?.name ?? obj.text_box?.name ?? obj.grid?.name ?? obj.chart?.name);
  });
  return [...acc, ...values];
}, []);

console.log(result);

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

An empty array is being returned by the Model.find() method after sorting

let query = Tour.find(JSON.parse(queryStr)); if (req.query.sort) { query = query.sort(req.query.sort);//a string 'ratings' } const tours = await query; res.status(200).json({ status: 'success', requestedAt: req.requestTime, ...

Is there a way to retrieve the value of a round slider using jQuery?

After creating a round slider using resources from various websites, I encountered an issue. I am trying to retrieve the current value of the slider and store it in a database, but I am facing difficulties in doing so. Although the slider displays the va ...

How can I determine in Python whether an array contains all elements of another array or list, even if there are duplicates present?

In exploring methods to determine if one set is a subset of another, I am struggling to find a succinct solution for checking if all elements in a list or array, including duplicates, are present in another list or array. For instance, consider the hypothe ...

Importing from the project root is a common practice in Typescript

My project structure is organized as follows: .dist classes namespace1 module.js public routes index.js app.js config.js src classes namespace1 module.ts public routes index.ts app.ts config.ts The .dist f ...

Rendering Based on Conditions in React Native

I'm a beginner in the world of React Native and coding and I'm looking to display text based on certain variables (as shown below). If isPlayer === true && base.length === 1, then display x Else if isPlayer === true && base.leng ...

Can the axios version be displayed during runtime?

I have incorporated axios into my project using npm import axios from 'axios' Is there a way to print the version of axios in the console after the entire application has been compiled? ...

How can I resolve the error message "Incompatible types: expecting string, but receiving a JSON array"?

JSON Data: { "events": ["wedding", "wed"], "event_location": ["", ""], "event_studio": [ ["makeover", "epica", "Raddisson"], ["makeover", "epica"], ["Raddisson", "makeover", "contours"] ], "event_studio_location": [ ["Ernakulam", "thrissur ...

Retrieving all elements within a nested JSON array in PostgreSQL

My current challenge involves creating an SQL query to fetch DNS answer data for visualization in Grafana using TimescaleDB. I am facing difficulties querying multiple elements at once in Postgres. The JSON structure I'm trying to work with is as foll ...

Modifying the information depending on the option chosen from the dropdown menu using angularJS

I have a dropdown menu where I can choose between two options, and when selected, the corresponding data is displayed. However, I would like to display the data that is inside a div tag instead. Check out this Fiddle Demo HTML: <div ng-controller="Ct ...

What is the best method to obtain the user id within a Redux action?

I am striving to display only user-related items, so I am attempting to retrieve items by sending a request for data to the user id /api/items/:userid. Utilizing Redux store in this process. Here is my server-side code snippet: router.get("/:userid", (req ...

Should you stick with pre-defined styles or switch to dynamic inline style changes?

I am currently developing a custom element that displays playing cards using SVG images as the background. I want to make sure that the background image changes whenever the attributes related to the card's suit or rank are updated. From what I under ...

Using PHP to project MongoDB data on an embedded document array with the positional operator

When trying to retrieve a specific array from an embedded document based on certain criteria in PHP, I am facing issues. The output either displays all arrays in the document or just the first one. Here is my code: $dept->findOne(['$and' => ...

What is the process of using JavaScript code to read a text file?

Trying to use Google Charts while reading data from a text file. The code in JS is written for this purpose: function readTextFile(file){ var rawFile = new XMLHttpRequest(); rawFile.open("GET", file, false); // using synchronous call var allTe ...

How to pre-fill 3 formgroups when initializing in Angular 2?

I currently have this code that allows users to add a new set of fields. However, I am looking to have the component render out 3 sets of data upon initialization. Currently, one set of fields is generated using the initRateRow function. How can I modify ...

Search across the entire table in your React application with Global

Having trouble implementing global search with the new Material UI Next table component. I have a handleSearch method that takes an event as a parameter and uses regex to check if the event.target.value matches any data in the table. However, when I dele ...

Steps for replicating rows in a numpy array depending on the value within each row

My objective is to duplicate rows in numpy arrays based on the numerical value of the first element in each row. If this value is 1, I don't want to duplicate the row, but if it's 3, I need that row to be replicated three times. I've attempt ...

How to create a JsonPath query in C# using Newtonsoft Json.NET for a null property

Suppose we have a JSON array containing: [ { "id": 1, "name": "abc" }, { "id": 2 }, { "id": 3, "name": "def" } ] In this scenario, if we use th ...

Difficulty in adding a simple return to render an array in React for list creation

After establishing a basic object, I noticed that it contained an internal object named "orders" with an array of toppings like "Cheese" and "Bacon". To further explore this structure, I segregated the array and directed it to a function called renderToppi ...

Restricting user access to a route based on its type to enhance security and control

Currently, I have a React, Redux, and Next.js app up and running. Within my redux store, there is a user object that contains an attribute called "type". Each type of user has its own set of "routes" they are allowed to access. I am looking for the most e ...

Avoid the presence of HTML tags in the content before using the Google Translate API for

I have recently learned about the <span class="e;notranslate"e;> </span> tag that is used to prevent text from being translated within the span element. My goal now is to send content with HTML tags to the Translate API and have it return with ...