Merging items in an array of objects that share common values

Displayed below is an array containing categories and the corresponding solutions they belong to. Each category is unique while solutions may repeat.

const categories = [
  { category: 'Patch Leads', solution: 'Data Solutions' },
  { category: 'Cables', solution: 'Data Solutions' },

  { category: 'Nails', solution: 'Hardware' },
  { category: 'Locks', solution: 'Hardware' },
  { category: 'Screws', solution: 'Hardware' },

  { category: 'Cabinets', solution: 'Cabinet Solutions' },
  { category: 'Swing Frames', solution: 'Cabinet Solutions' },
  { category: 'Racks', solution: 'Cabinet Solutions' },

  { category: 'Fire Cables', solution: 'Fire Solutions' },

];

A new array of solution objects needs to be returned in the following format. All necessary data for this format is accessible during iteration, including index values for ids; however, there are challenges in structuring the code correctly.

const solutions = [
  {
    id: "0",
    name: "Data Solutions",
    categories: [
      {
        id: "0",
        name: "Cables",
        slug: "cables"
      },
      {
        id: "1",
        name: "Patch Leads",
        slug: "patch-leads"
      }
    ]
  },
  {
    id: "1",
    name: "Hardware",
    categories: [
      {
        id: "0",
        name: "Nails",
        slug: "nails"
      },
      {
        id: "1",
        name: "Locks",
        slug: "locks"
      },
      {
        id: "2",
        name: "Screws",
        slug: "screws"
      }
    ]
  },
  {
    id: "2",
    name: "Cabinet Solutions",
    categories: [
      {
        id: "0",
        name: "Cabinets",
        slug: "cabinets"
      },
      {
        id: "1",
        name: "Swing Frames",
        slug: "swing-frames"
      },
      {
        id: "2",
        name: "Racks",
        slug: "racks"
      }
    ]
  },
  {
    id: "3",
    name: "Fire Solutions",
    categories: [
      {
        id: "0",
        name: "Fire Cables",
        slug: "fire-cables"
      }
    ]
  }
]

Answer №1

If you want to achieve that, the reduce() method can be used. During the iteration process, check if the current item already exists and append the current category to the existing item if it does. If not, create a new item with the current category.

const categories = [ { category: 'Patch Leads', solution: 'Data Solutions' }, { category: 'Cables', solution: 'Data Solutions' }, { category: 'Nails', solution: 'Hardware' }, { category: 'Locks', solution: 'Hardware' }, { category: 'Screws', solution: 'Hardware' }, { category: 'Cabinets', solution: 'Cabinet Solutions' }, { category: 'Swing Frames', solution: 'Cabinet Solutions' }, { category: 'Racks', solution: 'Cabinet Solutions' }, { category: 'Fire Cables', solution: 'Fire Solutions' }, ];

var solutions = categories.reduce((acc, curr) => {
  let item = acc.find(item => item.name === curr.solution);

  if (item) {
    item.categories.push({
      "id": item.categories.length,
      "name": curr.category,
      "slug": curr.category.toLowerCase().replace(' ', '-')
    });
  } else {
    acc.push({
      "id": acc.length,
      "name": curr.solution,
      "categories": [{
        "id": 0,
        "name": curr.category,
        "slug": curr.category.toLowerCase().replace(' ', '-')
      }]
    });
  }

  return acc;
}, []);

console.log(solutions);

Answer №2

The following code snippet showcases a process of creating an intermediate array map that correlates solutions to categories. This map is then utilized to produce the desired output format by leveraging the keys and values within the mapped Object.

const categories = [
  { category: 'Patch Leads', solution: 'Data Solutions' },
  { category: 'Cables', solution: 'Data Solutions' },

  { category: 'Nails', solution: 'Hardware' },
  { category: 'Locks', solution: 'Hardware' },
  { category: 'Screws', solution: 'Hardware' },

  { category: 'Cabinets', solution: 'Cabinet Solutions' },
  { category: 'Swing Frames', solution: 'Cabinet Solutions' },
  { category: 'Racks', solution: 'Cabinet Solutions' },

  { category: 'Fire Cables', solution: 'Fire Solutions' },

];

const solutionMap = categories.reduce((acc, item) => {
 if (!acc[item.solution]) 
   acc[item.solution] = [];
 acc[item.solution].push(item.category); 
 return acc;
}, {});

const solutions = Object.entries(solutionMap).map(([key, val], id) => ({
  id,
  name: key,
  categories: val.map((category, idx) => ({ id: idx, name: category, slug: category.toLowerCase().replace(' ', '-') }))
}));

console.log(solutions);

Answer №3

To optimize object creation, consider utilizing specific classes.

const types = [
    { type: 'Phones', category: 'Electronics' },
    { type: 'Laptops', category: 'Electronics' },

    { type: 'Sunglasses', category: 'Accessories' },
    { type: 'Watches', category: 'Accessories' },

    { type: 'Chairs', category: 'Furniture' },
    { type: 'Desks', category: 'Furniture' },
];

class Type{
    constructor(id,name){
        this.id = id;
        this.name = name;
        this.label = name;
    }
}
class NewItem {
    constructor(id,name,types=[]) {
        this.id = id;
        this.name = name;
        this.types = types;
    }
}
let categories = [];

categories.push(new NewItem(0, types[0].category,[new Type(0,types[0].type)]));

let newIndex = 0;
let newId = 1;

for(index in types){
    if(categories[newIndex].name !== types[index].category){
        categories.push(new NewItem(index, types[index].category,[new Type(0,types[index].type)]));
        newIndex++;
        newId=1;
    }else{
        categories[newIndex].types.push(new Type(newId,types[index].type));
        newId++;
    }
}

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

Package for validating forms in Meteor using React

Looking for recommendations on a Meteor React form validation package or custom validation code that's compatible with components. Need something similar to jQuery validate, but specifically designed to work seamlessly with Meteor and React. ...

Struggling to align legacy reCaptcha code

I need help centering an old reCaptcha code within a form, but my attempts have not been successful. Here is what I have tried: margin:0 auto; margin:0 auto !important; text-align:center; This is the HTML code I am working with: <p class="captcha"&g ...

Is it possible to update state multiple times within a single function using setState?

I'm currently working on a card guessing game and facing an issue where I need to update the state multiple times within the same clickHandler function. However, due to the asynchronous nature of state updates, it always reverts back to the previous s ...

Utilizing parentIds to construct a hierarchical array structure in PHP

I am currently facing a challenge in setting up a multi-level list structure with the use of parentId to establish parent-child relationships. Initially, the top-level items have a parentId set as NULL. Here is an illustration of some sample entries: < ...

Tips for detecting a new day with server-side JavaScript

I am currently developing a website that includes a schedule for teachers. I have encountered the need to delete elapsed days data from a database. What is the most effective method to monitor when it is exactly 12 midnight? If I were to use setInterval( ...

How shouldjs makes value verification effortless for unordered arrays

In my express.js application, I'm currently using supertest and should.js as my preferred testing framework. However, I've encountered some difficulties when it comes to testing for specific values within an unordered array. After referring to t ...

Tips for preventing the browser from freezing when incorporating a large HTML chunk retrieved through AJAX requests

I've developed a web application that showcases information about various items. Initially, only a small portion of the items are displayed at the top level. Upon loading the page for the first time and displaying these initial items, I make an AJAX r ...

The function you are attempting to call, ReactHtmlParser, is not recognized as

I'm currently using react-html--parser in combination with Next.js to convert an HTML string into actual HTML code. Here's my code snippet: import dynamic from "next/dynamic"; const ReactHtmlParser = dynamic( () => { retu ...

Evaluating a string or object for compatibility

In my possession, I have a PHP array that has been encoded in JSON format: <script> var registeredEmails = <?php echo(json_encode($emails)); ?>; </script> To verify that this is functioning properly, I conduct the following test: conso ...

jQuery's Same Origin Policy compared to the Browser's Policy when using OData

I am currently developing an AJAX application that interacts with an OData endpoint. Through my experimentation with the Netflix OData feed, I have encountered a puzzling issue: Whenever I send an .ajax() request to a specific URL (for instance, ), I rece ...

Vue - Pull out several components from main file

In my Vue.js project, I have been using the .vue component specs format to write components. An interesting observation I made is that plain JavaScript can export these components when loaded from vue files. For instance, a component defined in index.vue c ...

The impact on 'int a' and 'int a[]' when altered without pointers outside of the main() function

Modifying an element of an array is straightforward, as shown in the following code snippet. #include <stdio.h> void func(int a[]){ a[0] = 56; } int main() { int a[1]={34}; func(a); printf("%d" ,a[0]); return 0; } Ho ...

Is it possible to utilize a for loop or a function to accomplish this task and create a concise and flexible solution for this particular array?

Hello there! I'm new to this platform and eager to learn. Any chance you could share some information with me and help me study a bit? var people = [ [1, 'Dimitri', 'Microsoft'], [2, 'Mike', 'Micro ...

Guide to implementing AWS Cognito TOTP MFA functionality

I'm struggling with utilizing this library: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js specifically, in the section that mentions Use case 27. Selecting the MFA method and authenticating using TOTP. Whi ...

Substitute the identifier with the name

My Current Data I currently have some data stored in json format shown below: var info = [{id: 1, name="AB", position=1}, {id: 2, name="CD", boss= 1, position=2}, {id: 3, name="EF", boss= 1, position=2}, {id: 4, name=" ...

Reduce the total distance between two sets of points that do not share any common points

I am working with a multidimensional array that represents distances between two groups of points, one colored blue and the other red. import numpy as np distance=np.array([[30,18,51,55], [35,15,50,49], [36,17,40,32], ...

What could be causing this JavaScript/CSS animation to only function on the initial instance and not the subsequent ones?

I've been attempting to apply this transition effect to multiple circles, but only the first one triggers it no matter where they are positioned on the page. javascript let circles = document.querySelectorAll('.circle') circles.forEach(cir ...

Why is JavaScript globally modifying the JSON object?

I have a few functions here that utilize the official jQuery Template plugin to insert some JSON data given by our backend developers into the variables topPages and latestPages. However, when I use the insertOrHideList() function followed by the renderLis ...

Adding an array into MongoDb

Looking for guidance on how to store an array from PHP into MongoDb. For example: $cars = array("Volvo", "BMW", "Toyota"); I would like to create a document like this: { { "user":user1, cars":["volvo","BMW","Toyota"] } } C ...

a smart method for retrieving elements from a JSON array

In my possession is a JSON array data = '[{"beatles": [ {"name":"Paul McCartney","value": "http://www.paulmccartney.com"}, {"name": "John Lennon","value": "http://www.johnlennon.it"}, {"name":"George Ha ...