0

i have an array of object like below. and i want to reconstruct it based on its category. and convert all subcategory into a string.

 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"
 }]

know i need to get result like below, with 2 elements only, category and a subcategory string separated by comma as below.


> 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 sub category is a string value here.

i did somthing like this

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

the output was

JS: Staples
JS: Dals & Pulses
JS: Staples
JS: Ghee & Oils
JS: Staples
JS: Atta & Flours
JS: Staples
JS: Masalas & Spices
JS: Snacks and Beverages
JS: Biscuits
JS: Snacks and Beverages
JS: Chips
JS: Snacks and Beverages
JS: Namkeen & Snacks
JS: Snacks and Beverages
JS: Tea
JS: Snacks and Beverages
JS: Coffe

I'm Really confused on how to construct a new array with about about. if i try to push it in new array. i don't want category to add multiple times, if i try to push sub category into array i need to convert it to a string before push. but how any ideas is thankfulll

3
  • what is the expected output Commented Jun 28, 2019 at 6:46
  • 'var result = ' --- > look here in the code Commented Jun 28, 2019 at 6:47
  • the same question is posted by this(stackoverflow.com/users/11404646/modi) user and deleted by him some minutes ago Commented Jun 28, 2019 at 6:54

4 Answers 4

1

The shortest approach is to collect the data with a Map and render the wanted result by taking key and values.

It uses, in order of logic,

  • reducing the data with Array#reduce, where a Map acts as accumulator and return value,

  • this Map is handed over to Array.from, where an iterables is used for converting to an array with or without a further mapping function, which is given, here with

  • a callback which takes a key/value pair and returns an object by taking 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 simplified version of above with an object as hash table for same categories.

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; }

Sign up to request clarification or add additional context in comments.

3 Comments

it's really easy and good. but i didn't understand the code. can you give some useful tutorial links to understand your answer. I'm a fresher.
you could follow the links above and start with reduce. this is an important feature to fold an array to a single value.
i read it, but still didn't understand your logic, it's too complicated and very simple. thank you very very much.
0

Try like this. I have looped the main array and pushed the first element in to result array then I pushed the first occurence of a category to availableCat array also. and then I identified the next same category using availableCat arry and then I concatenate the data.

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)

Comments

0

Here another way to do this. Using lodash and Array.reduce

var _ = require('lodash')
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 grouped = _.groupBy(main,'category')

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

Comments

0

You need to first group the array of objects by the category property using Array#prototype#reduce after doing that join the subcategories by using Array#prototype#join.

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.