Combining attributes of objects in an array

Is the title accurate for my task? I have an array structured like this:

{
  "someValue": 1,
  "moreValue": 1,
  "parentArray": [
    {
      "id": "2222",
      "array": [
        {
          "type": "test",
          "id": "ID-100"
        },
        {
          "type": "test1",
          "id": "ID-200"
        }
      ]
    },
    {
      "id": "5555",
      "array": [
        {
          "type": "test",
          "id": "ID-100"
        },
        {
          "type": "test1",
          "id": "ID-200"
        }
      ]
    },
    {
      "id": "444",
      "array": [
        {
          "type": "test",
          "id": "ID-100"
        },
        {
          "type": "test1",
          "id": "ID-200"
        }
      ]
    }
  ]
}

I aim to merge all "array" properties into a new array, resulting in a structure similar to this:

{
  "someValue": 1,
  "moreValue": 1,
  "array": [
    {
      "type": "test",
      "id": "ID-100"
    },
    {
      "type": "test1",
      "id": "ID-200"
    },
    {
      "type": "test",
      "id": "ID-4400"
    },
    {
      "type": "test1",
      "id": "ID-500"
    },
    {
      "type": "test",
      "id": "ID-600"
    },
    {
      "type": "test1",
      "id": "ID-700"
    }
  ]
}

What would be the optimal method to consolidate these properties using Typescript? I'm seeking a Typescript/Angular-friendly solution as this data needs to be utilized to generate HTML elements.

Answer №1

If you want to combine inner arrays within your parentArray, you can achieve this by utilizing the reduce method:

let object = {
      "someValue": 1,
      "moreValue": 1,
      "parentArray": [
        {
          "id": "2222",
          "array": [
            {
              "type": "test",
              "id": "ID-100"
            },
            {
              "type": "test1",
              "id": "ID-200"
            }
          ]
        },
        {
          "id": "5555",
          "array": [
            {
              "type": "test",
              "id": "ID-100"
            },
            {
              "type": "test1",
              "id": "ID-200"
            }
          ]
        },
        {
          "id": "444",
          "array": [
            {
              "type": "test",
              "id": "ID-100"
            },
            {
              "type": "test1",
              "id": "ID-200"
            }
          ]
        }
      ]
    }

    let newObject = {
        someValue: object.someValue,
        moreValue: object.moreValue,
        array: object.parentArray.reduce((previous, current) => [...previous, ...current.array],[])
    }
    
    console.log(newObject)

Answer №2

Here is an alternative approach:

const data = {
  valueA: 1,
  valueB: 1,
  mainArray: [
    {
      id: "1111",
      items: [
        {
          category: "example",
          itemId: "ID-123"
        },
        {
          category: "sample",
          itemId: "ID-456"
        }
      ]
    },
    {
      id: "2222",
      items: [
        {
          category: "example",
          itemId: "ID-123"
        },
        {
          category: "sample",
          itemId: "ID-456"
        }
      ]
    },
    {
      id: "3333",
      items: [
        {
          category: "example",
          itemId: "ID-123"
        },
        {
          category: "sample",
          itemId: "ID-456"
        }
      ]
    }
  ]
};

let newData = {
  ...data,
  items: Object.values(data.mainArray).flatMap(item => item.items)
};

delete newData.mainArray;

console.log(newData);

Answer №3

If you need to transform data, consider using a mapping function. Personally, I find lodash to be quite handy in these situations. You can check out the documentation here: https://lodash.com/docs/4.17.15#flatMap

const destination = {
    someValue: source.someValue,
    moreValue: source.moreValue,
    array: _.flatMap(source.parentArray, (value) => value.array)
};

Answer №4

If you want to extract values using map, use the following code:

this.data.parentArray.map(item => item.array)
:

Here is an example:

var result = {
  someValue: this.data.someValue,
  moreValue: this.data.moreValue,
  array: this.data.parentArray.map(item => item.array)
};

See Working Demo Here

Answer №5

If you want to test out the next solution (which supports "infinite" nesting), give this a try:

function collectDescendants(inputArr) {
  return inputArr.reduce((output, element) => [...output, ...(element.array ? collectDescendants(element.array) : [element])], []);
}

Then simply use the function like so:

collectDescendants(your_object.parentArray);

See Demo Here

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 best way to line up changing column values with changing row values in an HTML table?

In its current state, the data appears as follows without alignment: The data columns are housed within a single variable due to the presence of multiple excel tabs with varying columns. Within the tr tag, rows are checked to match specific columns. The ...

What is the best way to remove query string parameters prior to running a function when a button is clicked?

I'm facing an issue trying to implement a button that filters events based on their tags. The problem arises when the tag value in the query string parameter does not clear when other buttons are clicked. Instead, the new filter tag value adds up with ...

Upgrading from Angular v6 to v8: Troubleshooting the issue of "The loader "datatable.component.css" did not return a string error"

I am currently in the process of updating my Angular project from version 6 to version 8. However, I encountered an error message in the console: ERROR: The loader "foo/node_modules/@swimlane/ngx-datatable/release/components/datatable.component.css" di ...

Utilize the class or interface method's data type

In the context of a child component calling a callback provided by its parent, this situation is commonly seen in AngularJS. As I am utilizing TypeScript, I aim to implement strong typing for the callback in the child component. Here is the initial stat ...

`Angular2 - exploring the complexities of function scope`

I'm facing a challenge while working on my Angular2 Sample with the http module. Here is a snippet from my component: app.loginComponent = ng.core.Component({ selector: 'login', templateUrl: 'app/login/login.html&ap ...

Angular8 Material Grid displaying headers and tiles, experiencing slight resizing issue with mat-grid-tile content

Exploring Angular8 Material: Grid Layout with Headers and Tiles Currently, I am delving into the workings of the grid system within Angular Material. I am dynamically fetching components and organizing them within a grid. While the grid list and tiles are ...

Challenges of Mocking Functions in Different Files When Testing with Jest

I'm currently facing a challenge with writing tests for the CreateVendor function using Jest and Supertest. My issue lies in how to effectively mock the dependencies (generateSalt, hashPassword) in order to correctly test the behavior of the function. ...

Trigger Function on Input Change in Angular 2

Key aspects of component nesting: export class Child { @Input() public value: string; public childFunction(){...} } Main component responsibilities: export class Parent { public value2: string; function1(){ value2 = "a" } function2( ...

Challenges with Typescript Integration in Visual Studio 2013

Currently diving into typescript as a newbie while going through the Angular tutorial using Visual Studio 2013 for work, which is also new to me. The frustrating part is that Visual Studio seems to be assuming I am going to use a different language (judgin ...

Steps for implementing a button to erase all created polygons in Leaflet and Geoman

I'm currently utilizing Geoman-free in conjunction with Leaflet to create a map where I can draw polygons. My objective is to develop a custom button within my Angular UI that can clear all the drawn polygons. How can this be achieved? Update: Let m ...

What is the best way to handle various sections with changing structures within a complex form using react-hook-form?

I am working on a complex form that has sections A, B, and C, each of which can be in shape A1 or A2, B1 or B2, C1, or C2. Users are required to fill out settings based on whether the section is set to "advanced" or "basic". I want users to submit the enti ...

Is there a method to add columns to an Angular material table dynamically?

I'm encountering an issue with creating dynamic tables using Angular Material tables. Since the table is reliant on an interface, I have a set number of columns. What I'm aiming for is to generate a table dynamically based on the server's re ...

encountered an error stating module '@angular/compiler-cli/ngc' could not be located while attempting to execute ng serve

Here is the content of my package.json file: { "name": "cal-euc", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build&qu ...

Storing basic input values for a function

I am currently working on developing a versatile method that is capable of accepting any number of parameters, while storing the input type for future use. Let's take a look at an example: const customizedFunction = <A extends any[]>(innerFunct ...

The NbDatePicker does not display certain Spanish names

One issue I'm facing is with the Nb-DatePicker component in my project. I tried using {provide: LOCALE_ID, useValue: "es-MX"} in my app.component to display it in Spanish. However, when February, April, May, August, or December are selected, ...

What are the best ways to enhance change detection efficiency in Angular?

One issue I am facing involves two components and a service. It appears that when moving from the view of a routed component to elements in different components like a matMenu and an input field, the routed component seems to refresh itself. This becomes p ...

Tips for sending a parameter to an onClick handler function in a component generated using array.map()

I've been developing a web application that allows users to store collections. There is a dashboard page where all the user's collections are displayed in a table format, with each row representing a collection and columns showing the collection ...

Initiating the ngOnInit lifecycle hook in child components within Angular

I am facing an issue with controlling the behavior of child components in my Angular application. The problem arises when switching between different labels, causing the ngOnInit lifecycle hook of the children components not to trigger. The main component ...

The transformation from className to class attribute does not occur for custom elements in JSX

I recently encountered an issue with one of my React components where the "className" attribute was being converted to "classname" in the resulting HTML, instead of the expected "class" attribute. The component had a custom element definition as follows: ...

"Exploring the dynamic duo of Angular2 and ng2Material

I am currently facing an issue with the styling in my code while using ng2Material with Angular2. First: A demonstration of Material style functioning properly can be seen in this plunker. When you click on the button, you will notice an animation effect. ...