获取JavaScript中嵌套数组的子元素。

huangapple go评论94阅读模式
英文:

how to get the children of a deeply nested array in js

问题

以下是您要翻译的内容:

  1. 我有这些数据
  2. const data = [
  3. {
  4. name: "Car",
  5. id: "19",
  6. count: "20",
  7. depth: "1",
  8. children: [
  9. {
  10. name: "Wheel",
  11. id: "22",
  12. count: "3",
  13. depth: "2",
  14. children: [
  15. {
  16. name: "Engine",
  17. id: "101",
  18. count: "1",
  19. depth: "3",
  20. children: [
  21. {
  22. name: "Engine and Brakes",
  23. id: "344",
  24. count: "1",
  25. depth: "4",
  26. children: []
  27. }
  28. ]
  29. }
  30. ]
  31. }
  32. ]
  33. },
  34. {
  35. name: "Bike",
  36. id: "3",
  37. count: "12",
  38. depth: "1",
  39. children: [
  40. {
  41. name: "SpeedBike",
  42. id: "4",
  43. count: "12",
  44. depth: "2",
  45. children: []
  46. }
  47. ]
  48. }
  49. ];

我想要按照以下方式传递多个类别 ID:['101', '3'],并且只能获取传递的类别 ID 的直接子项,应该看起来像这样:

  1. [
  2. {
  3. name: "Engine and Brakes",
  4. id: "344",
  5. count: "1",
  6. },
  7. {
  8. name: "SpeedBike",
  9. id: "4",
  10. count: "12",
  11. }
  12. ]

如果没有传递类别 ID,则希望能够默认查看父项和直接子项。如下所示:

  1. [
  2. {
  3. name: "Car",
  4. id: "19",
  5. count: "20"
  6. },
  7. {
  8. name: "Wheel",
  9. id: "22",
  10. count: "3"
  11. },
  12. {
  13. name: "Bike",
  14. id: "3",
  15. count: "12",
  16. },
  17. {
  18. name: "SpeedBike",
  19. id: "4",
  20. count: "12"
  21. }
  22. ]

如果传递的类别 ID 没有子项,我希望返回一个空数组:

  1. []

我想避免使用 forforeachwhile。如何实现这一点?我尝试使用 mapfilter,但没有成功。有人可以帮忙吗?哪种方法最好?

我正在使用 JavaScript 和 TypeScript。

嵌套数组可能会有多个深层级。

英文:

I have this data

  1. const data = [
  2. {
  3. name: "Car",
  4. id: "19",
  5. count: "20",
  6. depth: "1",
  7. children: [
  8. {
  9. name: "Wheel",
  10. id: "22",
  11. count: "3",
  12. depth: "2",
  13. children: [
  14. {
  15. name: "Engine",
  16. id: "101",
  17. count: "1",
  18. depth: "3",
  19. children: [
  20. {
  21. name: "Engine and Brakes",
  22. id: "344",
  23. count: "1",
  24. depth: "4",
  25. children: []
  26. }
  27. ]
  28. }
  29. ]
  30. }
  31. ]
  32. },
  33. {
  34. name: "Bike",
  35. id: "3",
  36. count: "12",
  37. depth: "1",
  38. children: [
  39. {
  40. name: "SpeedBike",
  41. id: "4",
  42. count: "12",
  43. depth: "2",
  44. children: []
  45. }
  46. ]
  47. }
  48. ];

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:

  1. [
  2. {
  3. name: "Engine and Brakes",
  4. id: "344",
  5. count: "1",
  6. },
  7. {
  8. name: "SpeedBike",
  9. id: "4",
  10. count: "12",
  11. }
  12. ]

If no category id is passed I want to be able to see the parent and the direct children as default. like below:

  1. [
  2. {
  3. name: "Car",
  4. id: "19",
  5. count: "20"
  6. },
  7. {
  8. name: "Wheel",
  9. id: "22",
  10. count: "3"
  11. },
  12. {
  13. name: "Bike",
  14. id: "3",
  15. count: "12",
  16. },
  17. {
  18. name: "SpeedBike",
  19. id: "4",
  20. count: "12"
  21. }
  22. ]

If the category id passed does not have children I want to return an empty array.:

  1. []

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:

  1. type Category = {
  2. name: string;
  3. id: string;
  4. count: string;
  5. depth: string;
  6. children: Category[];
  7. };

Implementation:

  1. const getCategoriesChildren = (
  2. categoryIds: Category['id'][],
  3. categories: Category[],
  4. ) => {
  5. const foundChildren: Pick<Category, 'id' | 'count' | 'name'>[] = [];
  6. if (categoryIds.length === 0) {
  7. return categories.reduce<Pick<Category, 'id' | 'count' | 'name'>[]>(
  8. (acc, category) => {
  9. acc.push(mapCategory(category), ...category.children.map(mapCategory));
  10. return acc;
  11. },
  12. [],
  13. );
  14. }
  15. const stack = [...categories];
  16. while (stack.length) {
  17. const category = stack.pop();
  18. if (!category) continue;
  19. if (categoryIds.includes(category.id)) {
  20. foundChildren.push(
  21. ...category.children.map((childCategory) => ({
  22. name: childCategory.name,
  23. id: childCategory.id,
  24. count: childCategory.count,
  25. })),
  26. );
  27. }
  28. stack.push(...category.children);
  29. }
  30. return foundChildren;
  31. };

Usage:

  1. // [{
  2. // "name": "SpeedBike",
  3. // "id": "4",
  4. // "count": "12"
  5. // }, {
  6. // "name": "Engine and Brakes",
  7. // "id": "344",
  8. // "count": "1"
  9. // }]
  10. console.log(getCategoriesChildren(['101', '3'], data));
  11. // [{
  12. // "name": "Car",
  13. // "id": "19",
  14. // "count": "20"
  15. // }, {
  16. // "name": "Wheel",
  17. // "id": "22",
  18. // "count": "3"
  19. // }, {
  20. // "name": "Bike",
  21. // "id": "3",
  22. // "count": "12"
  23. // }, {
  24. // "name": "SpeedBike",
  25. // "id": "4",
  26. // "count": "12"
  27. // }]
  28. console.log(getCategoriesChildren([], data));

playground

英文:

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:

  1. type Category = {
  2. name: string;
  3. id: string;
  4. count: string;
  5. depth: string;
  6. children: Category[];
  7. };

Implementation:

  1. const getCategoriesChildren = (
  2. categoryIds: Category[&#39;id&#39;][],
  3. categories: Category[],
  4. ) =&gt; {
  5. const foundChildren: Pick&lt;Category, &#39;id&#39; | &#39;count&#39; | &#39;name&#39;&gt;[] = [];
  6. if (categoryIds.length === 0) {
  7. return categories.reduce&lt;Pick&lt;Category, &#39;id&#39; | &#39;count&#39; | &#39;name&#39;&gt;[]&gt;(
  8. (acc, category) =&gt; {
  9. acc.push(mapCategory(category), ...category.children.map(mapCategory));
  10. return acc;
  11. },
  12. [],
  13. );
  14. }
  15. const stack = [...categories];
  16. while (stack.length) {
  17. const category = stack.pop();
  18. if (!category) continue;
  19. if (categoryIds.includes(category.id)) {
  20. foundChildren.push(
  21. ...category.children.map((childCategory) =&gt; ({
  22. name: childCategory.name,
  23. id: childCategory.id,
  24. count: childCategory.count,
  25. })),
  26. );
  27. }
  28. stack.push(...category.children);
  29. }
  30. return foundChildren;
  31. };

Usage:

  1. // [{
  2. // &quot;name&quot;: &quot;SpeedBike&quot;,
  3. // &quot;id&quot;: &quot;4&quot;,
  4. // &quot;count&quot;: &quot;12&quot;
  5. // }, {
  6. // &quot;name&quot;: &quot;Engine and Brakes&quot;,
  7. // &quot;id&quot;: &quot;344&quot;,
  8. // &quot;count&quot;: &quot;1&quot;
  9. // }]
  10. console.log(getCategoriesChildren([&#39;101&#39;, &#39;3&#39;], data));
  11. // [{
  12. // &quot;name&quot;: &quot;Car&quot;,
  13. // &quot;id&quot;: &quot;19&quot;,
  14. // &quot;count&quot;: &quot;20&quot;
  15. // }, {
  16. // &quot;name&quot;: &quot;Wheel&quot;,
  17. // &quot;id&quot;: &quot;22&quot;,
  18. // &quot;count&quot;: &quot;3&quot;
  19. // }, {
  20. // &quot;name&quot;: &quot;Bike&quot;,
  21. // &quot;id&quot;: &quot;3&quot;,
  22. // &quot;count&quot;: &quot;12&quot;
  23. // }, {
  24. // &quot;name&quot;: &quot;SpeedBike&quot;,
  25. // &quot;id&quot;: &quot;4&quot;,
  26. // &quot;count&quot;: &quot;12&quot;
  27. // }]
  28. console.log(getCategoriesChildren([], data));

playground

huangapple
  • 本文由 发表于 2023年5月17日 17:27:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76270550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定