地图深入 collection
map deep in collection
我需要得到我拥有的大 collection 中的所有 "id" 和 "name"。一个数组 ob objects,其中包含 objects(等)的数组。
如果不对尽可能多的级别手动执行 foreaches,我无法让它工作,这很丑陋。
我正在使用 Lodash,所以使用它的解决方案会很不错。
这是 collection 的样子:
[
{
"id": 1,
"name": "Living",
"numberStories": 0,
"subcategories": {
"data": [
{
"id": 2,
"name": "Fashion",
"numberStories": 0,
"subcategories": {
"data": [
{
"id": 3,
"name": "Accessories",
"numberStories": 0,
"subcategories": {
"data": [
]
}
},
{
"id": 4,
"name": "Kid's Fashion",
"numberStories": 0,
"subcategories": {
"data": [
]
}
}, (... etc)
所以它需要在 objects 的每个数组中查找子类别并收集 id 和名称,这样我最终得到所有级别的所有 ids 名称。
谢谢。
没有必要为此使用 lodash。使用 .reduce()
的简单递归函数可以为您完成工作
function flattenId(inArray){
return inArray.reduce(function(output, elem){
output.push(elem.id);
return output.concat(flattenId(elem.subcategories.data));
}, []);
}
如上所述,使用原生 javascript 可能更容易做到这一点,因为它是递归的。这与之前的答案相同,但使用了 ES6 的一些很酷的特性(解构、rest 参数、箭头函数、默认参数),并且它会保存对父 id 的引用,以便您可以在需要时重建类别树.
const categories=[{id:1,name:"Living",numberStories:0,subcategories:{data:[{id:2,name:"Fashion",numberStories:0,subcategories:{data:[{id:3,name:"Accessories",numberStories:0,subcategories:{data:[]}},{id:4,name:"Kid's Fashion",numberStories:0,subcategories:{data:[]}}]}}]}}];
const flattenCategories = (categories, parent = null, ret = []) =>
categories.reduce((acc, { id, name, subcategories: { data } }) =>
acc.concat(
{ id, name, parent },
...flattenCategories(data, id)
)
, ret)
console.log(
flattenCategories(categories)
)
.as-console-wrapper { top: 0; max-height: 100% !important }
这是一个使用 object-scan 的解决方案。根据您的用例,使用库可能有点矫枉过正,但如果需要,它可以为您提供更大的灵活性
// const objectScan = require('object-scan');
const categories = [{ id: 1, name: 'Living', numberStories: 0, subcategories: { data: [{ id: 2, name: 'Fashion', numberStories: 0, subcategories: { data: [{ id: 3, name: 'Accessories', numberStories: 0, subcategories: { data: [] } }, { id: 4, name: "Kid's Fashion", numberStories: 0, subcategories: { data: [] } }] } }] } }];
const r = objectScan(['**[*].id'], {
filterFn: ({ context, value, parents }) => {
context.push({
id: value,
name: parents[0].name,
parent: parents.length > 2 ? parents[3].id : null
});
}
})(categories, []);
console.log(r);
// => [ { id: 4, name: "Kid's Fashion", parent: 2 }, { id: 3, name: 'Accessories', parent: 2 }, { id: 2, name: 'Fashion', parent: 1 }, { id: 1, name: 'Living', parent: null } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
免责声明:我是object-scan
的作者
我需要得到我拥有的大 collection 中的所有 "id" 和 "name"。一个数组 ob objects,其中包含 objects(等)的数组。
如果不对尽可能多的级别手动执行 foreaches,我无法让它工作,这很丑陋。
我正在使用 Lodash,所以使用它的解决方案会很不错。
这是 collection 的样子:
[
{
"id": 1,
"name": "Living",
"numberStories": 0,
"subcategories": {
"data": [
{
"id": 2,
"name": "Fashion",
"numberStories": 0,
"subcategories": {
"data": [
{
"id": 3,
"name": "Accessories",
"numberStories": 0,
"subcategories": {
"data": [
]
}
},
{
"id": 4,
"name": "Kid's Fashion",
"numberStories": 0,
"subcategories": {
"data": [
]
}
}, (... etc)
所以它需要在 objects 的每个数组中查找子类别并收集 id 和名称,这样我最终得到所有级别的所有 ids 名称。
谢谢。
没有必要为此使用 lodash。使用 .reduce()
的简单递归函数可以为您完成工作
function flattenId(inArray){
return inArray.reduce(function(output, elem){
output.push(elem.id);
return output.concat(flattenId(elem.subcategories.data));
}, []);
}
如上所述,使用原生 javascript 可能更容易做到这一点,因为它是递归的。这与之前的答案相同,但使用了 ES6 的一些很酷的特性(解构、rest 参数、箭头函数、默认参数),并且它会保存对父 id 的引用,以便您可以在需要时重建类别树.
const categories=[{id:1,name:"Living",numberStories:0,subcategories:{data:[{id:2,name:"Fashion",numberStories:0,subcategories:{data:[{id:3,name:"Accessories",numberStories:0,subcategories:{data:[]}},{id:4,name:"Kid's Fashion",numberStories:0,subcategories:{data:[]}}]}}]}}];
const flattenCategories = (categories, parent = null, ret = []) =>
categories.reduce((acc, { id, name, subcategories: { data } }) =>
acc.concat(
{ id, name, parent },
...flattenCategories(data, id)
)
, ret)
console.log(
flattenCategories(categories)
)
.as-console-wrapper { top: 0; max-height: 100% !important }
这是一个使用 object-scan 的解决方案。根据您的用例,使用库可能有点矫枉过正,但如果需要,它可以为您提供更大的灵活性
// const objectScan = require('object-scan');
const categories = [{ id: 1, name: 'Living', numberStories: 0, subcategories: { data: [{ id: 2, name: 'Fashion', numberStories: 0, subcategories: { data: [{ id: 3, name: 'Accessories', numberStories: 0, subcategories: { data: [] } }, { id: 4, name: "Kid's Fashion", numberStories: 0, subcategories: { data: [] } }] } }] } }];
const r = objectScan(['**[*].id'], {
filterFn: ({ context, value, parents }) => {
context.push({
id: value,
name: parents[0].name,
parent: parents.length > 2 ? parents[3].id : null
});
}
})(categories, []);
console.log(r);
// => [ { id: 4, name: "Kid's Fashion", parent: 2 }, { id: 3, name: 'Accessories', parent: 2 }, { id: 2, name: 'Fashion', parent: 1 }, { id: 1, name: 'Living', parent: null } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
免责声明:我是object-scan
的作者