如何在js中显示特定类别id的子项并最终将它们展平

问题描述 投票:0回答:3

我有这个数据

  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,如下所示 ['22', '3'] 并能够获取传递的类别 ID 的所有子项,它们应该如下所示:


[
  {
    name: "Engine",
    id: "101",
    count: "1",
  },
  {
    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
但没有运气。有人可以帮忙吗?最好的方法是什么?

我正在使用js和ts。

嵌套数组可以很深,有多个深度。

javascript arrays multidimensional-array mapping hierarchy
3个回答
1
投票

下面是一个简单的参考,供您使用Recursive_function来做

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: []
        }
      ]
    }
  ];
 

const searchData = (arr,categories=[],matched = false) => {
    let result = []
    for(a of arr){
        let includes = matched ? true: categories.includes(a.id)
        if(includes || matched){
            result.push(...a.children)
        }
        result.push(...searchData(a.children,categories,includes))
    }
    return result;
}

const filterData = (arr,categories=[]) => {
    let result = []
    if(!!categories && categories.length > 0){
        result = searchData(arr,categories)
    } else {
        for(a of arr){
            result.push(a,...a.children)
        }
    }
    result = result.map(({id,name,count,...reset})=> ({id,name,count}))
    return result
}

console.log(filterData(data,[]))
console.log("--------------------")
console.log(filterData(data,["3","22"]))


0
投票

我们仍将使用您previous related question中描述的approach。但是,我们将稍微更新算法。

现在堆栈将存储带有附加

isDesired?: boolean
属性的类别,这表明该类别是具有我们要查找的id的类别的后代。 如果该类别的 id 在
categoryIds
中,那么我们将其子级推入带有
isDesired: true
的堆栈中。 我们决定在以下条件下将类别的孩子放入
foundChildren
:如果类别id在
categoryIds
category.isDesired
true

带评论的游乐场


0
投票

调用这个函数-

function GetFilteredOrNonFilteredData(data, stringofids = [])
{
    const resolvedData = GetData(data);
    if (stringofids.length <= 0) {
        return resolvedData.map(item => {
        delete item.parentid;
        return item
        });
    }
    return resolvedData.filter((item) => {
        return stringofids.includes(item.parentid) ?? item;
    })
}

在文件中包含这个函数 -

function GetData(data, id = 0) {
const allData = [];

function processItem(item, parentId) {
    item.parentid = parentId;
    allData.push(item);
    if (item.children.length > 0) {
        item.children.forEach(child => processItem(child, item.id));
    }
}

data.forEach(item => {
    processItem(item, id);
});

return allData;
}

例子-

console.log(GetFilteredOrNonFilteredData(data,["101","22"]));
© www.soinside.com 2019 - 2024. All rights reserved.