Combining sub-objects under a shared parent in Javascript

In my data structure, I have parent objects with nested arrays of children. Here's an example:

[
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

I want to combine parent nodes with the same 'fullName' and merge their children together. The desired result is:

[
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      },
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

I've tried various lodash solutions based on different resources, but haven't quite achieved the desired output. Do you have any suggestions or ideas?

@Andy, one solution that seemed promising was the following function:

function mergeNames (arr) {
    return _.chain(arr).groupBy('fullName').mapValues(function (v) {
        return _.chain(v).map('fullName').flattenDeep();
    }).value();
}

console.log(mergeNames(array));

However, this outputs a "lodash wrapper" and doesn't correctly combine the children. I suspect this might be because of having the same identifier (fullName) at both child and parent levels. Running this code provides the following console output:

{
  "Certificate": [
    "Certificate"
  ],
  "InstalledPackage": [
    "InstalledPackage",
    "InstalledPackage"
  ],
  "Network": [
    "Network"
  ]
}

Answer №1

To achieve this task, utilize the Array.prototype methods in the following way:

let information = [
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
];

let result = information.reduce((res, elem) => {
let arrForChecking = res.filter((el) => el.fullName === elem.fullName);

if (arrForChecking.length) {
arrForChecking[0].children.push(elem.children[0]);

return res;
}

return res = res.concat(elem);
}, []);

console.log(result);

Answer №2

To efficiently group and combine data, you can establish key definitions for grouping while utilizing a hash table to store groups and then populate the result array with individual groups.

var data = [{ fullName: "Certificate", checked: false, children: [{ type: "Certificate", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Certificate-1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package2" }] }, { fullName: "Network", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Network1" }] }], 
    hashTable = Object.create(null), 
    keys = ['fullName', 'checked'], 
    groupedData = [];

data.forEach(function (obj) {
    var key = keys.map(function (k) { return obj[k]; }).join('|');
    if (!hashTable[key]) {
        hashTable[key] = {};
        keys.forEach(function (k) { hashTable[key][k] = obj[k]; });
        hashTable[key].children = [];
        groupedData.push(hashTable[key]);
    }
    hashTable[key].children = hashTable[key].children.concat(obj.children);
});

console.log(groupedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Using ES6 syntax:

var data = [{ fullName: "Certificate", checked: false, children: [{ type: "Certificate", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Certificate-1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package2" }] }, { fullName: "Network", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Network1" }] }],
    hashTable = Object.create(null),
    keys = ['fullName', 'checked'],
    groupedData = [];

data.forEach(function (obj) {
    var key = keys.map(k => obj[k]).join('|');
    if (!hashTable[key]) {
        hashTable[key] = Object.assign({}, obj);
        groupedData.push(hashTable[key]);
        return;
    }
    hashTable[key].children.push(...obj.children);
});

console.log(groupedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №3

here is the code snippet:

data = [
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

final_data = []
i=-1
data.forEach(function(item, index){
  if(index>0){
    i=i+1
    if(data[index]['fullName'] === data[i]['fullName']) {
      item['children'] = item['children'].concat(data[i]['children'])
      final_data[final_data.length - 1] = item
    } else {
      final_data.push(item)
    }
  } else {
    final_data.push(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

Converting a bytearray into a Jar file: A step-by-step guide

I'm attempting to load a jar file from a byte array directly into memory without saving it as a file. I've created a custom ClassLoader for this purpose, but when I try to use it and load a class, I encounter a ClassNotFoundException. Custom Cla ...

I am experiencing an issue where the button I place inside a material-ui table is unresponsive to clicks

Here is the structure of my table: <TableContainer component={Paper} style={{height: "40vh", width: "90vh"}}> <Table size="small" sx={{ minWidth: 200 }}> <TableHea ...

Ways to retrieve a specific object property from an array of objects within a click event listener?

I have instantiated multiple object constructors and stored them in an array which I loop over to display as a list. Now, I am trying to extract the name property from that list to use in an onclick event handler (not included in this code). I am unsure of ...

Having trouble removing a row from Mysql database using Node.js

Recently, I developed a pet shop web application using nodeJS and MySql. Everything was working smoothly until I encountered an issue with deleting pets by their pet_id. Upon attempting to delete using pet_id 'pa04', I received the following erro ...

Is the dragging behavior of a rotated image different than that of the original image when using CSS rotation?

While working on a CSS grid to showcase images rotated at 60 degrees for a diagonal view, I encountered an issue. I wanted users to have the ability to drag and drop images within the grid, but when they drag an image, it moves as if it weren't rotate ...

Check to see if two words are identical in PHP

Could you please check the word I've written in the text field? If the two words are the same, I should receive a message saying "They are the same." <?php function array_random($arr, $num = 1) { shuffle($arr); $r = array(); for ($i = ...

Updating the HTTP request header in AngularJS without requiring a page refresh

I'm in the process of developing a website that utilizes ngRoute for page navigation. When a user logs in, a form will appear and upon successful login, the controller will modify the http header for subsequent requests. However, I am encountering an ...

The concept of looping within Angular directives

Exploring various recursive angular directive Q&A's can lead to different solutions that are commonly utilized: Creating HTML incrementally based on runtime scope state Check out this example [Stack Overflow discussion] Here's another exa ...

Tips for utilizing ajax function to refresh database entries

I am working with a customer information table that is populated from a database. The last column in this table contains an edit button which, when clicked, shows a popup window with text fields pre-filled with database values. I want users to be able to u ...

Accessing a modal in Bootstrap 4 by clicking on an anchor link will automatically open the

I am implementing a bootstrap 4 modal with anchor tags that trigger the opening of the modal. Here is an example structure: <div class="experience"> <div class="container"> <div class="row"> <div cl ...

Effortless bug tracking in Chrome developer tools

When I'm debugging, I want the code to be displayed in Chrome browser (or another browser like Edge) exactly as it was written. Even when using pretty print, the code still appears unreadable. For example, a block of code written in my IDE: {provideD ...

Discover and modify the values of all the keys within nested JSON arrays and objects using JavaScript

I have a nested JSON data structure consisting of arrays and objects. I am looking to convert all the key values from English to Spanish using JavaScript, NodeJS, or AngularJS. { "firstrootkey" : [ //Array of 6 objects { //1st object ...

How to simulate a particular class from a node package using Jest mocks

In my project, I'm looking to specifically mock the Socket class from the net node module. The documentation for this can be found here. Within my codebase, there is a class structured similar to the following... import { Socket } from 'net&apo ...

What is the best way to pass the values of two interlinked drop-down menus through an AJAX post request to a Django view?

Presently, I am encountering an issue with sending the values of two dropdowns to a django view. My code would have functioned correctly if the dropdowns were independent. Unfortunately, this is not the case as the first one updates the second one. Therefo ...

Utilizing jquery.validate.min.js for efficient form validation

Here is my JavaScript validate function: $("form[id='form']").validate({ Name: "required", submitHandler: function() { formSubmit(); } }); Not only do I wa ...

What is the method for transforming latitude and longitude coordinates into a physical address for a website?

I'm working with an API that provides latitude and longitude coordinates, and I need to retrieve the address information (city, area, etc.) based on these values. For example, there is a website like where if we enter the IP address of a location, i ...

Issue encountered while trying to gather vertex coordinates from a file using Blender's from_pydata function

I encountered the following error: Error: Array length mismatch (expected 3, got 13) TypeError: a float is required Traceback (most recent call last): File "\Test.py", line 393, in from_pydata File "C:\Program Files (x86)\Blender Foundation ...

How come using a query object as a parameter for .limit() returns an empty array?

I am currently working on a mongoose query setup where I have a custom queryObject containing key-value pairs for specific records. If a key-value pair does not exist in the req.query, it is omitted from the queryObject. Oddly enough, when setting the que ...

Information submitted through an ajax request does not get saved in the $_POST array

After successfully executing an AJAX request using GET, I decided to try POST this time. However, when attempting to send data, a baffling error message appeared in the console - NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED: 'JavaScript component does ...

Encrypting data using pidCrypt in a combination of Javascript and PHP

Currently, I am in the process of developing an encryption system to secure sensitive information on my website. My web hosting service requires an additional fee for SSL, which I am not prepared to invest in at this moment. I experimented with utilizing ...