英文:
how to get the children of a deeply nested array in js
问题
以下是您要翻译的内容:
我有这些数据
const data = [
{
name: "Car",
id: "19",
count: "20",
depth: "1",
children: [
{
name: "Wheel",
id: "22",
count: "3",
depth: "2",
children: [
{
name: "Engine",
id: "101",
count: "1",
depth: "3",
children: [
{
name: "Engine and Brakes",
id: "344",
count: "1",
depth: "4",
children: []
}
]
}
]
}
]
},
{
name: "Bike",
id: "3",
count: "12",
depth: "1",
children: [
{
name: "SpeedBike",
id: "4",
count: "12",
depth: "2",
children: []
}
]
}
];
我想要按照以下方式传递多个类别 ID:['101', '3'],并且只能获取传递的类别 ID 的直接子项,应该看起来像这样:
[
{
name: "Engine and Brakes",
id: "344",
count: "1",
},
{
name: "SpeedBike",
id: "4",
count: "12",
}
]
如果没有传递类别 ID,则希望能够默认查看父项和直接子项。如下所示:
[
{
name: "Car",
id: "19",
count: "20"
},
{
name: "Wheel",
id: "22",
count: "3"
},
{
name: "Bike",
id: "3",
count: "12",
},
{
name: "SpeedBike",
id: "4",
count: "12"
}
]
如果传递的类别 ID 没有子项,我希望返回一个空数组:
[]
我想避免使用 for
、foreach
和 while
。如何实现这一点?我尝试使用 map
和 filter
,但没有成功。有人可以帮忙吗?哪种方法最好?
我正在使用 JavaScript 和 TypeScript。
嵌套数组可能会有多个深层级。
英文:
I have this data
const data = [
{
name: "Car",
id: "19",
count: "20",
depth: "1",
children: [
{
name: "Wheel",
id: "22",
count: "3",
depth: "2",
children: [
{
name: "Engine",
id: "101",
count: "1",
depth: "3",
children: [
{
name: "Engine and Brakes",
id: "344",
count: "1",
depth: "4",
children: []
}
]
}
]
}
]
},
{
name: "Bike",
id: "3",
count: "12",
depth: "1",
children: [
{
name: "SpeedBike",
id: "4",
count: "12",
depth: "2",
children: []
}
]
}
];
I want to pass in multiple category ids as follows ['101', '3'] and be able to only get the direct children of the passed category ids which should look like this:
[
{
name: "Engine and Brakes",
id: "344",
count: "1",
},
{
name: "SpeedBike",
id: "4",
count: "12",
}
]
If no category id is passed I want to be able to see the parent and the direct children as default. like below:
[
{
name: "Car",
id: "19",
count: "20"
},
{
name: "Wheel",
id: "22",
count: "3"
},
{
name: "Bike",
id: "3",
count: "12",
},
{
name: "SpeedBike",
id: "4",
count: "12"
}
]
If the category id passed does not have children I want to return an empty array.:
[]
I want to avoid using for
foreach
and while
. How can I achieve this? I have tried using map
and filter
but no luck. Can someone please help? What is the best approach to this?
I am using js and ts.
The nested array can be deep with multiple deep levels.
答案1
得分: 2
以下是您要翻译的内容:
There is no built-in functions to do that. Instead, there are two approaches that we can take: iterative and recursive.
The recursive approach requires O(logN) extra space for call stack size; thus, we will use the iterative approach.
Algorithm:
- If category ids are provided:
- Populate stack with categories of the first level
- While the stack is not empty:
- Pop category from the stack
- If category id is in the desired ids array:
- Map through the category's children and retrieve the desired properties
- Push children of the category to stack
- else:
- Loop through the first level.
- Push the parent and children of the parent.
Type for category:
type Category = {
name: string;
id: string;
count: string;
depth: string;
children: Category[];
};
Implementation:
const getCategoriesChildren = (
categoryIds: Category['id'][],
categories: Category[],
) => {
const foundChildren: Pick<Category, 'id' | 'count' | 'name'>[] = [];
if (categoryIds.length === 0) {
return categories.reduce<Pick<Category, 'id' | 'count' | 'name'>[]>(
(acc, category) => {
acc.push(mapCategory(category), ...category.children.map(mapCategory));
return acc;
},
[],
);
}
const stack = [...categories];
while (stack.length) {
const category = stack.pop();
if (!category) continue;
if (categoryIds.includes(category.id)) {
foundChildren.push(
...category.children.map((childCategory) => ({
name: childCategory.name,
id: childCategory.id,
count: childCategory.count,
})),
);
}
stack.push(...category.children);
}
return foundChildren;
};
Usage:
// [{
// "name": "SpeedBike",
// "id": "4",
// "count": "12"
// }, {
// "name": "Engine and Brakes",
// "id": "344",
// "count": "1"
// }]
console.log(getCategoriesChildren(['101', '3'], data));
// [{
// "name": "Car",
// "id": "19",
// "count": "20"
// }, {
// "name": "Wheel",
// "id": "22",
// "count": "3"
// }, {
// "name": "Bike",
// "id": "3",
// "count": "12"
// }, {
// "name": "SpeedBike",
// "id": "4",
// "count": "12"
// }]
console.log(getCategoriesChildren([], data));
英文:
There is no built-in functions to do that. Instead, there are two approaches that we can take: iterative and recursive.
The recursive approach requires O(logN) extra space for call stack size; thus, we will use the iterative approach.
Algorithm:
- If category ids are provided:
- Populate stack with categories of the first level
- While the stack is not empty:
- Pop category from the stack
- If category id is in the desired ids array:
- Map through the category's children and retrieve the desired properties
- Push children of the category to stack
- else:
- Loop through the first level.
- Push the parent and children of the parent.
Type for category:
type Category = {
name: string;
id: string;
count: string;
depth: string;
children: Category[];
};
Implementation:
const getCategoriesChildren = (
categoryIds: Category['id'][],
categories: Category[],
) => {
const foundChildren: Pick<Category, 'id' | 'count' | 'name'>[] = [];
if (categoryIds.length === 0) {
return categories.reduce<Pick<Category, 'id' | 'count' | 'name'>[]>(
(acc, category) => {
acc.push(mapCategory(category), ...category.children.map(mapCategory));
return acc;
},
[],
);
}
const stack = [...categories];
while (stack.length) {
const category = stack.pop();
if (!category) continue;
if (categoryIds.includes(category.id)) {
foundChildren.push(
...category.children.map((childCategory) => ({
name: childCategory.name,
id: childCategory.id,
count: childCategory.count,
})),
);
}
stack.push(...category.children);
}
return foundChildren;
};
Usage:
// [{
// "name": "SpeedBike",
// "id": "4",
// "count": "12"
// }, {
// "name": "Engine and Brakes",
// "id": "344",
// "count": "1"
// }]
console.log(getCategoriesChildren(['101', '3'], data));
// [{
// "name": "Car",
// "id": "19",
// "count": "20"
// }, {
// "name": "Wheel",
// "id": "22",
// "count": "3"
// }, {
// "name": "Bike",
// "id": "3",
// "count": "12"
// }, {
// "name": "SpeedBike",
// "id": "4",
// "count": "12"
// }]
console.log(getCategoriesChildren([], data));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论