嵌套数组上的AngularTS递归过滤器

时间:2018-10-14 07:28:23

标签: angular typescript recursion lambda filter

我遇到一个问题,那就是需要一个函数,该函数可以递归地遍历嵌套的对象数组并根据视图列表中是否存在元素来过滤掉元素。

例如,给定一个列表:

[{
    "label": "Heading",
    "items": [{
      "label": "Subheading",
      "items": [{
          "id": "item1_priv",
          "label": "item1"
        },
        {
          "id": "item_priv2",
          "label": "item2"
        },
        {
          "label": "Subheading",
          "items": [{
            "id": "item_priv3",
            "label": "item3"
          }]
        }
      ]
    }]
  },
  {
    "label": "Heading2",
    "items": [{
      "label": "Subheading",
      "items": [{
          "id": "item_priv4",
          "label": "item4"
        },
        {
          "id": "item_priv5",
          "label": "item5"
        }
      ]
    }]
  }
]

和视图列表:

canView = ['item1','item2','item4','item5']

该功能需要过滤列表中的item3,因为它不在canView中。

我已经做过一个可以做到这一点的函数:

public filterView(list: any[]): any {

  for (const item of list) {
    if (item.items) {
      item.items = this.filterView(item.items);
    } else {
      list = ((list.filter((i: any) => this.hasView(i.id))));
    }
  }

  return list;
}

但是,我的问题是:是否可以使用list.filter()将此函数重写为lambda?我是Angular to和Typescript的新手,所以我很难用过滤器(或嵌套过滤器)来绕过头绪,以便根据列表是否拥有项目遍历列表。

我的假设将是函数

list.filter(item => return(item.items && this.hasView(item.items.id)))

,但这似乎不适用于具有动态深度的列表。任何建议都将不胜感激,因为针对我所见过的类似问题的其他解决方案仅具有固定深度的列表。

1 个答案:

答案 0 :(得分:0)

我建议的唯一更改是对列表进行一次过滤,而不是在循环内进行过滤:

public filterView(list: any[]): any {

  for (const item of list) {
    if (item.items) {
      item.items = this.filterView(item.items);
    }
  }

  return list.filter((i: any) => this.hasView(i.id));
}

除此之外,鉴于filterView所做的两件事(过滤顶级列表和更改后代的子列表),在我看来,任何更简洁的编写方式都将很难理解。