[英]Merging two arrays based on Property
我有两个数组:一个包含类别,第二个包含项目。
我想使用lodash将所有项目项合并到其适当的类别数组中。 但是,我确实有一个问题。 由于这可以通过双foreach循环完成,因此有没有理由使用lodash?
数组1(类别):
"categories": [
{
"id": 1,
"name": "cat_1",
"items": []
},
{
"id": 11,
"name": "cat_2",
"items": []
},
{
"id": 61,
"name": "cat_3",
"items": []
}
]
数组2(包含项):
[
{
id: 15,
name: 'some_item',
category_id: 1,
category_name: 'cat_1',
},
{
id: 112,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
},
{
id: 235,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
},
]
所需的对象将如下所示:
"categories":
[
{
"id": 1,
"name": "cat_1",
"items": [
{
id: 15,
name: 'some_item',
category_id: 1,
category_name: 'cat_1',
}
]
},
{
"id": 11,
"name": "cat_2",
"items": [
{
id: 112,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
},
{
id: 235,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
}
]
},
{
"id": 61,
"name": "cat_3",
"items": []
}
]
这是使用普通ES5的方法:
const categories = [{id:1,name:"cat_1",items:[]},{id:11,name:"cat_2",items:[]},{id:61,name:"cat_3",items:[]}] const items = [{id:15,name:"some_item",category_id:1,category_name:"cat_1"},{id:112,name:"some_item",category_id:11,category_name:"cat_2"},{id:235,name:"some_item",category_id:11,category_name:"cat_2"}]; const result = categories.map(c => ({ ...c, items: items.filter(i => i.category_id === c.id) })); console.log(result);
由于Java的历史,它是一种非常特殊的语言。 它最初是一种非常不起眼的语言,几乎没有任何功能,尽管它已经发展了,但并非所有浏览器都支持所有功能。
这引起了像lodash,underscore,inmutable.js和jquery之类的库的出现,从而填补了Javascript标准库中的空白。
如您所见,现在JS具有非常方便的抽象,例如each
, map
, find
, filter
和reduce
,它们是跨语言的普遍理解的概念。 与使用for
循环编写低级的过程代码相比,这使代码更易于理解。
作为一个颜色说明,我开始使用ruby进行编程,它以拥有丰富的集合抽象的标准库而闻名。 结果,直到最近,我才注意到语言中的for
循环在哪里,即使实现高层抽象是必要的。
我从未使用过lodash,但是您是对的,可以使用foreach循环轻松完成此操作。 甚至没有两个foreach循环,只有一个带有'.find'或'.filter'的循环
(a)遍历每个项目并使用array.find
查找合适的类别,然后将项目输入到类别中
(b)遍历每个类别,并使用array.filter
查找适当的项目,然后将这些项目输入每个类别。
这是一种选择:
(()=>{
const categories = [{
"id": 1,
"name": "cat_1",
"items": []
},
{
"id": 11,
"name": "cat_2",
"items": []
},
{
"id": 61,
"name": "cat_3",
"items": []
}]
const items = [{
id: 15,
name: 'some_item',
category_id: 1,
category_name: 'cat_1',
},
{
id: 112,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
},
{
id: 235,
name: 'some_item',
category_id: 11,
category_name: 'cat_2',
}]
categories.forEach((cat) => {
cat.items = items.filter((item) => item.category_id === cat.id);
})
})()
您可以使用lodash _.keyBy()
按类别ID对项目进行分组,然后使用Array#map循环类别,并创建新的类别对象,其中项目取自itemsByCategory
:
const categories = [{"id":1,"name":"cat_1","items":[]},{"id":11,"name":"cat_2","items":[]},{"id":61,"name":"cat_3","items":[]}]; const items = [{"id":15,"name":"some_item","category_id":1,"category_name":"cat_1"},{"id":112,"name":"some_item","category_id":11,"category_name":"cat_2"},{"id":235,"name":"some_item","category_id":11,"category_name":"cat_2"}]; const itemsByCategory = _.groupBy(items, 'category_id'); const categoriesWithItems = categories.map(({ id, name, items }) => ({ id, name, items: items.concat(itemsByCategory[id]) })); console.log(categoriesWithItems);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
如您所见,我使用的唯一lodash方法是_.keyBy()
,我们可以将其替换为Array#reduce :
const categories = [{"id":1,"name":"cat_1","items":[]},{"id":11,"name":"cat_2","items":[]},{"id":61,"name":"cat_3","items":[]}]; const items = [{"id":15,"name":"some_item","category_id":1,"category_name":"cat_1"},{"id":112,"name":"some_item","category_id":11,"category_name":"cat_2"},{"id":235,"name":"some_item","category_id":11,"category_name":"cat_2"}]; const itemsByCategory = items.reduce((r, item) => { r[item.category_id] = item; return r; }, {}); const categoriesWithItems = categories.map(({ id, name, items }) => ({ id, name, items: items.concat(itemsByCategory[id]) })); console.log(categoriesWithItems);
因此,使用lodash主要是为了方便。 由于lodash是用JS编写的,因此您可以使用JS创建lodash所做的任何事情(ES6使工作更轻松),并且可以节省一些捆绑包的大小。 但是,lodash确实可以节省大量手写的,经过纯测试的代码,从而重新发明了轮子。 我建议使用lodash-es而不是lodash,因为es版本是模块化的,因此您可以导入所需的内容。 这可以在易用性和捆束尺寸之间取得平衡。
您可以为类别选择一个Map
,然后迭代项目以推送到相应的类别。
var object = { categories: [{ id: 1, name: "cat_1", items: [] }, { id: 11, name: "cat_2", items: [] }, { id: 61, name: "cat_3", items: [] }] }, items = [{ id: 15, name: 'some_item', category_id: 1, category_name: 'cat_1', }, { id: 112, name: 'some_item', category_id: 11, category_name: 'cat_2', }, { id: 235, name: 'some_item', category_id: 11, category_name: 'cat_2', }], map = new Map(object.categories.map(category => [category.id, category.items])); items.forEach(item => map.get(item.category_id).push(item)); console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.