如何根据对象的唯一数组进行分组并获得唯一的元素和字符串值的元素

时间:2019-06-28 06:44:53

标签: javascript

我有一个对象数组,如下所示。我想根据类别重新构建它。并将所有子类别转换为字符串。

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

知道我需要得到如下结果,仅包含2个元素,类别和以逗号分隔的子类别字符串,如下所示。


> 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' 
}],

此处的子类别是字符串值。

我做了这样的事

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

输出为

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

我真的很困惑如何构建大约为about的新数组。如果我尝试将其推入新数组。我不希望类别添加多次,如果我尝试将子类别推入数组,则需要在推入之前将其转换为字符串。但是什么想法是感激的

4 个答案:

答案 0 :(得分:1)

最短的方法是使用Map收集数据,并通过获取键和值来呈现所需的结果。

按逻辑顺序使用

  • 使用Array#reduce减少数据,其中Map充当累加器和返回值,

  • Map移交给Array.from,其中iterables用于转换为具有或不具有其他映射功能的数组,此处提供了

  • 采用键/值对并通过采用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; }

上述的简化版本,具有一个对象作为相同类别的哈希表。

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

答案 1 :(得分:0)

尝试这样。我循环了main数组并将第一个元素推入result数组,然后将类别的第一个出现也推到了availableCat数组中。然后我使用availableCat arry确定了下一个相同的类别,然后将数据连接起来。

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)

答案 2 :(得分:0)

这是另一种方法。使用lodash和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)

答案 3 :(得分:0)

在使用Array#prototype#reduce加入子类别之后,您需要先使用Array#prototype#join通过category属性对对象数组进行分组。

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