[英]Merge & Group Two Javascript array of objects and Group
我有两个对象数组。 一个数组包含项目列表,另一个数组包含类别列表。 我想基于categoryIds创建一个新的数组。 我尝试使用lodash。 但是,无法获得正确的解决方案。
我可以使用循环来做到这一点。 但是,我正在寻找更干净的方法。
var items = [
{
id: '001',
name: 'item1',
description: 'description of item1',
categoryId: 'cat1'
},
{
id: '002',
name: 'item2',
description: 'description of item2',
categoryId: 'cat2'
},
{
id: '003',
name: 'item3',
description: 'description of item3',
categoryId: 'cat1'
},
{
id: '004',
name: 'item4',
description: 'description of item4'
}
];
var categories = [
{
id: 'cat1',
name: 'Category1'
},
{
id: 'cat2',
name: 'Category2'
}
];
预期产量
[
{
categoryId: 'cat1',
name: 'Category1',
items: [
{
id: '001',
name: 'item1',
description: 'description of item1',
categoryId: 'cat1'
},
{
id: '003',
name: 'item3',
description: 'description of item3',
categoryId: 'cat1'
}
]
},
{
categoryId: 'cat2',
name: 'Category2',
items: [
{
id: '002',
name: 'item2',
description: 'description of item2',
categoryId: 'cat2'
}
]
},
{
categoryId: '',
name: '',
items: [
{
id: '004',
name: 'item4',
description: 'description of item4'
}
]
}
]
https://jsfiddle.net/sfpd3ppn/
谢谢您的帮助
以下是窍门:
var items = [{ id: '001', name: 'item1', description: 'description of item1', categoryId: 'cat1' }, { id: '002', name: 'item2', description: 'description of item2', categoryId: 'cat2' }, { id: '003', name: 'item3', description: 'description of item3', categoryId: 'cat1' }, { id: '004', name: 'item4', description: 'description of item4' } ]; var categories = [ { id: 'cat1', name: 'Category1' }, { id: 'cat2', name: 'Category2' } ]; var output = categories.concat([{id:'',name:''}]).map(function(v) { return { categoryId: v.id, name: v.name, items: items.filter(function(o) { return o.categoryId === v.id || !o.categoryId && !v.id; }) }; }); console.log(output);
我首先使用.concat()
创建一个新的.concat()
数组,该数组包含原始categories
项目以及一个“空”类别。 然后,我对该数组进行.map()
返回具有所需输出结构的类别对象,每个类别对象都有一个items
数组,该数组由.filter()
生成原始items
数组产生。
(请注意, output
中的items
数组包含对原始items
输入中相同对象的引用, 而不是它们的副本。如果要复制,可以在.filter()
之后添加另一个.map()
.filter()
。)
您可以使用reduce来实现所需的结果。 我们将从原始的categories
数组开始,并将items
数组减少到其中。
var items = [
{ id: '001', name: 'item1', description: 'description of item1', categoryId: 'cat1' },
{ id: '002', name: 'item2', description: 'description of item2', categoryId: 'cat2' },
{ id: '003', name: 'item3', description: 'description of item3', categoryId: 'cat1' },
{ id: '004', name: 'item4', description: 'description of item4' }
];
var categories = [
{ id: 'cat1', name: 'Category1' },
{ id: 'cat2', name: 'Category2' }
];
// Lets add the empty category at the beginning. This simplifies the logic.
categories.push({ id: '', name: '' });
// This is a function that will return a function to be used as a filter later on
function createFilter (category) {
return function (item) {
return item.id === category;
};
}
var mergedSet = items.reduce(function (previous, current) {
// Get the category ID of the current item, if it doesn't exist set to empty string
var categoryId = current.categoryId || '';
// Find the cateogry that matches the category ID
var category = previous.find(createFilter(categoryId));
// If the items property doesn't exists (we don't have any items), create an empty array
if (!category.items) { category.items = []; }
// Add the item the category
category.items.push(current);
// Return the current value that will be used in the next iteration.
// Note, the initial value of previous will be the intial value of categories.
return previous;
}, categories);
console.log(mergedSet);
/* Output
[
{ id: 'cat1',
name: 'Category1',
items:
[ { id: '001',
name: 'item1',
description: 'description of item1',
categoryId: 'cat1' },
{ id: '003',
name: 'item3',
description: 'description of item3',
categoryId: 'cat1' }
]
},
{ id: 'cat2',
name: 'Category2',
items:
[ { id: '002',
name: 'item2',
description: 'description of item2',
categoryId: 'cat2'
}
]
},
{ id: '',
name: '',
items:
[ { id: '004',
name: 'item4',
description: 'description of item4' } ] }
]
*/
假设变量categories
和items
的分配如上定义:
const keyedCategories = _(categories)
.concat({ id: '', name: '' })
.keyBy('id')
.value();
const groupedItems = _.groupBy(items, (item) => _.get(item, 'categoryId', ''));
const result = _.reduce(groupedItems, (acc, value, key) => {
const { id: categoryId, name } = keyedCategories[key];
return _.concat(acc, { categoryId, name, items: value });
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.