过滤嵌套数组的数值(删除不匹配两个组和子项的数值)管道

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

Filter nested array values (remove the ones that dont match both groups and children) pipe

问题

如何筛选出嵌套的子项和组,所以在下面的示例中,如果我搜索"Nest Name 3",那么只会返回Group B,只有Nested Name 3。

我有一个如下所示的数组:

items = [
    {
        "key": "Group A",
        "value": [
            {
                "name": "Nest Name 1"
            }
        }
    },
    {
        "key": "Group B",
        "value": [
            {
                "name": "Nest Name 2"
            },
            {
                "name": "Nest Name 3"
            }
        }
    }
]

在Angular管道中,我尝试以相同的格式返回嵌套名称与字符串匹配的组。所以在这种情况下,如果我搜索2,只有Group B应该返回,只有第一个嵌套对象应该返回。

我已经在非嵌套代码上使匹配工作:

items?.filter(item => searchText.split(' ').every(q => new RegExp(q, 'i').test(item[field]))

searchText是我要搜索的单词,field是字段的名称,在这种情况下是name。

我以为类似以下的东西会起作用:

var tempList = [];
items.filter(group => group.value.filter(item => searchText.split(' ').every(q => new RegExp(q, 'i').test(item[field])))).forEach(product => tempList.push(product));
return tempList;

但是,虽然它返回了正确的组,但实际的嵌套项没有被移除。

谢谢。

英文:

How to filter out nested children and groups, so in the below example if i searched for "Nest Name 3" then only Group B would be returned and only Nested Name 3.

I have an arrary like this:

items = [
    {
        "key": "Group A",
        "value": [
            {
              "name": "Nest Name 1"
            }
    },
    {
        "key": "Group B",
        "value": [
            {
              "name": "Nest Name 2"
            },
            {
              "name": "Nest Name 3"
            }
                 [
    }
]

And in an angular pipe i am trying to return (in the same format) groups where the nested name matches a string. So in this case if i searched for 2 then only Group b should be brought back and only the first nested object would be brought back.

I have my match working on none nested code:
items?.filter(item => searchText.split(' ').every(q => new RegExp(q, 'i').test(item[field]))

searchText is the word i am searching for and field is the name of the field in this case name.

I thought something like this would work:

var tempList = [];
    items.filter(group => group.value.filter(item => searchText.split(' ').every(q => new RegExp(q, 'i').test(item[field])))).forEach(product => tempList.push(product));
    return tempList;

but while it brings back the correct groups the actual nested items are not removed.

Thanks

答案1

得分: 0

要搜索您的items,您需要比较每个item.value的名称与您的searchText字符串,这也包括在每个group.value内。以下是执行此操作的代码:

const filterItems = (searchText: string): Group[] => {
  return items
    .filter((item) =>
      item.value.some((value) => isSearchValue(value, searchText))
    )
    .map((group) => {
      return {
        key: group.key,
        value: group.value.filter((value) =>
          isSearchValue(value, searchText)
        ),
      };
    });
};

使用some()方法来迭代值数组。
如果数组中至少有一个元素满足提供的测试函数,此方法将返回true

some方法的文档

isSearchValue函数可以如下所示:

const isSearchValue = (value: ItemValue, searchText: string): boolean => {
  return value.name.toLowerCase().includes(searchText.toLowerCase());
}

这里有以下类型和接口:

type ItemValue = { name: string };
interface Group {
  key: string;
  value: ItemValue[];
}

为了更好地理解发生了什么,我创建了一个带有输入搜索功能的StackBlitz示例

英文:

To search through your items, you need to compare the name of each item.value against your searchText string also inside each group.value. Here's the code to do so:

const filterItems = (searchText: string): Group[] => {
  return items
    .filter((item) =>
      item.value.some((value) => isSearchValue(value, searchText))
    )
    .map((group) => {
      return {
        key: group.key,
        value: group.value.filter((value) =>
          isSearchValue(value, searchText)
        ),
      };
    });
};

> The some() method was used to iterate through the array of values.
> This method returns true if at least one element in the array
> satisfies the provided testing function.
>
> Documentation for the some method

The function isSearchValue can be like this:

const isSearchValue = (value:ItemValue,searchText:string):boolean=>{
  return value.name.toLowerCase().includes(searchText.toLowerCase());
}

Where there are the following types and interfaces:

type ItemValue = {name:string};
interface Group{
  key:string;
  value:ItemValue[];
}

To give you a better idea of what's happening, I've created a StackBlitz example with an input search feature.

huangapple
  • 本文由 发表于 2023年2月8日 08:29:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380328.html
匿名

发表评论

匿名网友

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

确定