JavaScript如何过滤嵌套对象的数组

时间:2019-07-10 04:59:50

标签: javascript

我有这个数组。

const items = [
  { text: "Dashboard", roles: ["manager", "staff"] },
  {
    text: "User management",
    roles: ["admin", "manager", "staff"],
    children: [
      {
        text: "Create Suburb",
        roles: ["manager", "admin"]
      },
      {
        text: "View and Update Suburb",
        roles: ["staff"]
      },
      {
        text: "Create shoping mall"
      }
    ]
  }
];

我想在根对象和子数组的对象中同时过滤角色名称。

如果我将staff作为参数传递,则我的预期输出是

const items = [
  { text: "Dashboard", roles: ["manager", "staff"] },
  {
    text: "User management",
    roles: ["admin", "manager", "staff"],
    children: [
      {
        text: "View and Update Suburb",
        roles: ["staff"]
      }
    ]
  }
];

我到目前为止所做的是

const data = items.filter(element => {
  return element.roles.includes("staff");
});

这基本上过滤了根对象。但不过滤嵌套子数组的对象。如何使用JS实现此目标?

2 个答案:

答案 0 :(得分:0)

尝试使用递归(如果children也有children,则可以正常工作)

const items = [
  { text: "Dashboard", roles: ["manager", "staff"] },
  {
    text: "User management",
    roles: ["admin", "manager", "staff"],
    children: [
      {
        text: "Create Suburb",
        roles: ["manager", "admin"]
      },
      {
        text: "View and Update Suburb",
        roles: ["staff"]
      },
      {
        text: "Create shoping mall"
      }
    ]
  }
];

// recursive filter
function filter(group, role){
  return group.filter(item => {
    if(item.children){
      item.children = filter(item.children, role)
    }
    return item.roles && item.roles.includes(role);
  });
}

const data = filter(items, 'staff');

console.log(data);

答案 1 :(得分:0)

对于这些数组操作之王,我精减是更好的方法。

const items = [
  { text: 'Dashboard', roles: ['manager', 'staff'] },
  {
    text: 'User management',
    roles: ['admin', 'manager', 'staff'],
    children: [
      {
        text: 'Create Suburb',
        roles: ['manager', 'admin']
      },
      {
        text: 'View and Update Suburb',
        roles: ['staff']
      },
      {
        text: 'Create shoping mall'
      }
    ]
  }
]

function filterWithRoles(data,role) {
  return items.reduce((acc, item) => {
    if (item.roles.includes(role)) {
      item.children =
        item.children &&
        item.children.filter(child => child.roles && child.roles.includes(role))

      acc.push(item)
    }
    return acc
  }, [])
}

console.log(JSON.stringify(filterWithRoles(items,'staff'), null, 2))