Tips on organizing data according to an array of distinct objects and selecting unique elements and string values

In my array of objects, I need to reorganize it based on categories and convert all subcategories into strings.

 var main = [{
   "id": "1",
   "category": "Staples",
   "sub_category": "Dals & Pulses"
 }, {
   "id": "2",
   "category": "Staples",
   "sub_category": "Ghee & Oils"
 }, {
   "id": "3",
   "category": "Staples",
   "sub_category": "Atta & Flours"
 }, {
   "id": "4",
   "category": "Staples",
   "sub_category": "Masalas & Spices"
 }, {
   "id": "5",
   "category": "Snacks and Beverages",
   "sub_category": "Biscuits"
 }, {
   "id": "6",
   "category": "Snacks and Beverages",
   "sub_category": "Chips"
 }, {
   "id": "7",
   "category": "Snacks and Beverages",
   "sub_category": "Namkeen & Snacks"
 }, {
   "id": "8",
   "category": "Snacks and Beverages",
   "sub_category": "Tea"
 }]

I want to transform this data into the expected output below, with each category and its corresponding subcategories separated by commas:


> EXPECTED OUTPUT:-

 var result = [
{ 
   category: 'Staples',
   sub_cat: 'Dals & Pulses, Ghee & Oils, Atta & Flours, Masalas & Spices' },
{ 
   category: 'Snacks and Beverages',
   sub_cat: 'Biscuits, Chips, Namkeen & Snacks, Tea' 
}],

The subcategory values are string here.

This is what I have tried so far:

categories.map(key => {
                            sub_category.map(element => {
                                if (key.category == element.category) {
                                    console.log(key.category);
                                    console.log(element.sub_category);
                                }
                            });
                        });

However, the output was not as expected. I am struggling to construct a new array with the desired structure. Any ideas or suggestions would be greatly appreciated.

Answer №1

To efficiently gather and organize data, utilizing a Map can be the most effective method. This involves extracting key-value pairs from the data and formatting them accordingly.

The process follows this sequence:

  • Firstly, reduce the data using Array#reduce with a Map serving as an accumulator and output,

  • Next, pass this resulting Map to Array.from, which converts it to an array using an iterable and potentially a mapping function. Here, a callback is applied that processes each key/value pair to generate an object employing short hand properties.

var data = [{ id: "1", category: "Staples", sub_category: "Dals & Pulses" }, { id: "2", category: "Staples", sub_category: "Ghee & Oils" }, { id: "3", category: "Staples", sub_category: "Atta & Flours" }, { id: "4", category: "Staples", sub_category: "Masalas & Spices" }, { id: "5", category: "Snacks and Beverages", sub_category: "Biscuits" }, { id: "6", category: "Snacks and Beverages", sub_category: "Chips" }, { id: "7", category: "Snacks and Beverages", sub_category: "Namkeen & Snacks" }, { id: "8", category: "Snacks and Beverages", sub_category: "Tea" }],
    result = Array.from(
        data.reduce((m, { category, sub_category }) => m.set(category, [...(m.get(category) || []), sub_category]), new Map),
        ([category, sub_category]) => ({ category, sub_cat: sub_category.join(', ') })
    );

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

A more simplified version achieves the same outcome by using an object as a hash table for categorization.

var data = [{ id: "1", category: "Staples", sub_category: "Dals & Pulses" }, { id: "2", category: "Staples", sub_category: "Ghee & Oils" }, { id: "3", category: "Staples", sub_category: "Atta & Flours" }, { id: "4", category: "Staples", sub_category: "Masalas & Spices" }, { id: "5", category: "Snacks and Beverages", sub_category: "Biscuits" }, { id: "6", category: "Snacks and Beverages", sub_category: "Chips" }, { id: "7", category: "Snacks and Beverages", sub_category: "Namkeen & Snacks" }, { id: "8", category: "Snacks and Beverages", sub_category: "Tea" }],
    hash = {},
    item,
    i
    result = [];

for (i = 0; i < data.length; i++) {
    item = data[i];
    if (!hash[item.category]) {
        hash[item.category] = { category: item.category, sub_cat: item.sub_category };
        result.push(hash[item.category]);
        continue;
    }
    hash[item.category].sub_cat += ', ' + item.sub_category;
}

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

Answer №2

Here's a different approach to tackle this. I've iterated through the main array, adding the first element to the result array and capturing the first instance of each category in the availableCat array. Then, by using the availableCat array, I identified subsequent occurrences of the same category and concatenated the data accordingly.

var main = [{
   "id": "1",
   "category": "Staples",
   "sub_category": "Dals & Pulses"
 }, {
   "id": "2",
   "category": "Staples",
   "sub_category": "Ghee & Oils"
 }, {
   "id": "3",
   "category": "Staples",
   "sub_category": "Atta & Flours"
 }, {
   "id": "4",
   "category": "Staples",
   "sub_category": "Masalas & Spices"
 }, {
   "id": "5",
   "category": "Snacks and Beverages",
   "sub_category": "Biscuits"
 }, {
   "id": "6",
   "category": "Snacks and Beverages",
   "sub_category": "Chips"
 }, {
   "id": "7",
   "category": "Snacks and Beverages",
   "sub_category": "Namkeen & Snacks"
 }, {
   "id": "8",
   "category": "Snacks and Beverages",
   "sub_category": "Tea"
 }]

var result=[];
var availableCat = [];
main.forEach(function(data){
  if(availableCat.indexOf(data.category) >= 0){
    result.forEach(function(cnt){
      if(cnt.category == data.category){
        cnt.sub_cat += ', '+ data.sub_category
      }
    })
  }
  else {
    availableCat.push(data.category);
    var item = {"category" : data.category, "sub_cat" : data.sub_category}
    result.push(item);
  }
})

console.log(result)

Answer №3

Here's an alternative method using lodash and Array.reduce

var _ = require('lodash')
var items = [{
    "id": "1",
    "category": "Staples",
    "sub_category": "Dals & Pulses"
}, {
    "id": "2",
    "category": "Staples",
    "sub_category": "Ghee & Oils"
}, {
    "id": "3",
    "category": "Staples",
    "sub_category": "Atta & Flours"
}, {
    "id": "4",
    "category": "Staples",
    "sub_category": "Masalas & Spices"
}, {
    "id": "5",
    "category": "Snacks and Beverages",
    "sub_category": "Biscuits"
}, {
    "id": "6",
    "category": "Snacks and Beverages",
    "sub_category": "Chips"
}, {
    "id": "7",
    "category": "Snacks and Beverages",
    "sub_category": "Namkeen & Snacks"
}, {
    "id": "8",
    "category": "Snacks and Beverages",
    "sub_category": "Tea"
}]

var categorizedItems = _.groupBy(items,'category')

var groupedResult = Object.keys(categorizedItems).map(key => {
    return {
        category: key,
        sub_categories: categorizedItems[key].reduce((acc, curr) => acc = acc + curr.sub_category + ', ','')
    }
})
console.log(groupedResult)

Answer №4

To begin, organize the array of objects based on the category property by utilizing the Array#prototype#reduce method. Following that, concatenate the subcategories using the Array#prototype#join function.

const main = [
 {
   "id": "1",
   "category": "Staples",
   "sub_category": "Dals & Pulses"
 }, {
   "id": "2",
   "category": "Staples",
   "sub_category": "Ghee & Oils"
 }, {
   "id": "3",
   "category": "Staples",
   "sub_category": "Atta & Flours"
 }, {
   "id": "4",
   "category": "Staples",
   "sub_category": "Masalas & Spices"
 }, {
   "id": "5",
   "category": "Snacks and Beverages",
   "sub_category": "Biscuits"
 }, {
   "id": "6",
   "category": "Snacks and Beverages",
   "sub_category": "Chips"
 }, {
   "id": "7",
   "category": "Snacks and Beverages",
   "sub_category": "Namkeen & Snacks"
 }, {
   "id": "8",
   "category": "Snacks and Beverages",
   "sub_category": "Tea"
 }
];    

const result = Object.values(main.reduce((acc, curr) => { 
const { category, sub_category } = curr;
    if (!acc[category]) {
    acc[category] = {
        category: category,
        sub_category: [ sub_category ]
    };
}
else {
    acc[category].sub_category.push(sub_category);
}

return acc;
}, {}))
.map(x => {
const { sub_category, ...rest } = x;
return {
...rest,
sub_category: sub_category.join(', ')
};
});

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

Expanding the width of CSS dropdown menus according to their content

When attempting to create a dynamic dropdown menu, I encountered an issue where the values were skewed in Internet Explorer if they exceeded the width of the dropdown. To fix this problem, I added select:hover{width:auto;position:absolute}. However, now th ...

Tips for eliminating the domain name from the src URL attribute using Jquery

Is there a way to extract the img src attribute and retrieve only the image path without the domain name included? var imgurl = "http://nitseditor.dev/img/home/bg.jpg"; For instance, I would like to display img/home/bg.jpg instead of the full URL. Any id ...

Guide on making a PDF input field function like a regular input field with PDF.js

Whenever I encounter input fields in a pdf file, I attempt to use pdf js to interact with them. However, I have been facing challenges in doing so. Allow me to provide an example of my objective: const canvas = document.getElementById(`canvas-${this.page ...

Angular directive ceases to trigger

I am currently working on implementing an infinite scrolling directive. Initially, when the page loads and I start scrolling, I can see the console log. However, after the first scroll, it stops working. It seems like it only triggers once. Can anyone poi ...

Is there a way to display a message in a div container instead of using the alert box when there is a successful ajax response?

Hey there, I'm currently working on implementing error validation handling for a custom form that I've created. I'm looking to display the error messages in a designated div rather than using the standard browser alert box. Since I'm fa ...

The issue of infinite rendering caused by useState and how to effectively resolve it

I'm facing a strange issue in just a few lines of code, and I can't quite figure out what's happening behind the scenes. Here are the 4 lines causing trouble: function FarmerComponent(props) { let authCtx = useContext(AuthContext) let u ...

Is it possible to dynamically change an ngModel value directly from the component?

I'm currently immersed in an Angular project and my initial file setup was like this: dog.ts: export interface Dog { name: string; age: number; breed: string; } dog.component.ts: import { Dog } from '../dog'; @Component({ //setup ...

Sharing data between two Angular 2 component TypeScript files

I'm facing a scenario where I have two components that are not directly related as parent and child, but I need to transfer a value from component A to component B. For example: In src/abc/cde/uij/componentA.ts, there is a variable CustomerId = "sss ...

Error: The code is trying to access the property 'string' of an undefined variable. To fix this issue, make sure to

I encountered an issue after installing the https://github.com/yuanyan/boron library. The error message I received is: TypeError: Cannot read property 'string' of undefined Error details: push../node_modules/boron/modalFactory.js.module.expor ...

Expressjs Error- ReferenceError: cors has not been defined in this context

While working on creating a backend using ExpressJs, I encountered an error when running the backend. app.use(cors()) ^ ReferenceError: cors is not defined at Object.<anonymous> (C:\Users\hp\Desktop\Entri\kanba\ ...

Exploring the possibilities of page manipulation using React Native WebView

I'm encountering an issue with my implementation of react-native-webview. When I use it to open a webpage, the audio doesn't start playing automatically. Instead, I have to press a button for it to play. Is there a way to make the audio play dire ...

Ensure that data is not cached after the page is refreshed at regular intervals of x seconds

In the process of developing a news app, I have implemented a feature where a div with the class .new_feed is refreshed every 10 seconds to fetch new updates. However, I encountered an issue where if a new feed appears in the .new_feed div and is not cli ...

A script in PHP or JavaScript that dynamically generates two dual drop-down menus to assist with data selection

I have experience with php scripting, but I am facing challenges when trying to combine it with JavaScript. The issue arises when I have a form that includes dropdown menus for categories and subcategories. When a category is selected, the options in the s ...

Map Loader for GeoJson Leaflet Integration

Although my English skills are not perfect, I will do my best to explain my issue. I have some knowledge of javascript / html / ajax and I have created a webgis using Leaflet. The problem arises when loading a large geojson file onto the map - it takes qui ...

The error message "A form control with an invalid name attribute is not focusable" is displayed when attempting to use an input type file in Material

I've created a form using Material UI as a functional component, with the following structure: <form className={classes.container} onSubmit={show}> <Grid container item xs={12} alignItems="center"> <input accept=".xlsx,.xls" cl ...

What is the best method to convert data into the proper tensor format in Angular?

As I delve into my machine learning project, I find myself faced with the challenge of deploying my algorithm using Angular. While I have successfully uploaded the pretrained model and managed to import data from a CSV file, I am now struggling with proper ...

The transformation in the resulting array is evident when a nested array is altered after being concatenated using Array.concat

MDN explains concat as follows: The concat() function is utilized to combine two or more arrays without altering the original arrays. Instead, it produces a new array. Let's examine the code snippet below: Example 1 const array1 = [['a& ...

Merging object keys and values from JSON arrays based on their keys, using JavaScript

Is there a way to merge object keys' values from JSON arrays based on their key? json1 = [ {key:'xyz', value:['a','b']}, {key:'pqrs', value:['x','y']} ] json2 = ...

Trying to incorporate a PHP echo statement into the innerHTML of a button is ineffective

I have a piece of jQuery code that is not functioning as expected: $("#erase").click(function(){ $("#erase").attr("disabled", "disabled"); // Prevent double-clicking $(this).html("Erasing..."); $.post("erase.php", {target: $("#targ ...

Toggle the tooltip to reveal a hidden div by clicking, and then click again to close it

I've been working on implementing a toggle div with a tooltip. The issue I'm facing is that the tooltip initially displays "Click to open", but after opening the toggle, it should change to "Click to close". Can someone assist me in achieving thi ...