Javascript 如何在reactjs中过滤多数组列表

Javascript 如何在reactjs中过滤多数组列表,javascript,reactjs,Javascript,Reactjs,我尝试从具有多个数组的列表中实现搜索功能。所以我想从数组中搜索特定的关键字。我试过了,但它出错了 要从中搜索的数组: const listComponent=[{ id:0, 标题:“普通”, 子菜单:[{ 图像:“”, 部门名称:“, 副标题:“ }] }, { id:1, 标题:“计算”, 子菜单:[{ image:require(“../../assets/images/scaling.png”), 章节:“一个comp”, 副标题:“ }, { image:require(“../..

我尝试从具有多个数组的列表中实现搜索功能。所以我想从数组中搜索特定的关键字。我试过了,但它出错了

要从中搜索的数组:

const listComponent=[{
id:0,
标题:“普通”,
子菜单:[{
图像:“”,
部门名称:“,
副标题:“
}]
},
{
id:1,
标题:“计算”,
子菜单:[{
image:require(“../../assets/images/scaling.png”),
章节:“一个comp”,
副标题:“
},
{
image:require(“../../assets/images/ec2.png”),
章节:“两组”,
副标题:“
},
{
image:require(“../../assets/images/lambda.png”),
章节:“三合”,
副标题:“
},
{
image:require(“../../assets/images/zone.png”),
章节:“四合”,
副标题:“
}
]
},
{
id:2,
标题:"第二",
子菜单:[{
图像:“”,
部门名称:“,
副标题:“
}]
},
{
id:3,
标题:“第三次”,
子菜单:[{
图像:“”,
部门名称:“,
副标题:“
}]
},
{
id:4,
标题:“第四”,
子菜单:[{
图像:“”,
部门名称:“,
副标题:“
}]
}
];而不是

filterResult = components.filter((component, index) => {
  console.log(component.subMenu[index].secTitle);
  return component.subMenu[index].secTitle.toLowerCase().search(value) !== -1;
});
代码应该如下所示:

const listComponent = [
{
    id: 0,
    title: "Common",
    subMenu: [
    {
        image: "",
        secTitle: "abc",
        subTitle: ""
    }
    ]
},
{
    id: 1,
    title: "Common",
    subMenu: [
    {
        image: "",
        secTitle: "def",
        subTitle: ""
    }
    ]
}
]

let value = "abc";

let filterResult = listComponent.filter((component) => {
  return component.subMenu.findIndex((sub) => {
    return sub.secTitle === value;
  }) >= 0;
});

console.log(filterResult);

使用
Array.filter
Array.findIndex
的组合来获得所需的结果。 使用
String.includes
匹配secttitle中的子字符串

filterResult = filterResult.filter((component) => {
    const hasMatchingSubMenu = component.subMenu.findIndex((sub) => sub.secTitle.includes(value)) !== -1;
    if(hasMatchingSubMenu) {
        component.subMenu = component.subMenu.filter((sub) => sub.secTitle.includes(value));
    }
    return hasMatchingSubMenu;
});

尝试更改子菜单的键。理想情况下,不应使用索引作为键,因为子菜单的长度和顺序可能会更改。As键有助于识别哪些项已更改、已添加或已删除

试着换成这个

              ...
              {items.subMenu.map((submenu, i) => (
                  <li
                    key={`${submenu.secTitle}-${i}`}
                  >
                    <img src={submenu.image} alt="" />
                    <div>
                      <p className="secTitle">{submenu.secTitle}</p>
                      <p className="subTitle">{submenu.subTitle}</p>
                    </div>
                  </li>
                ))}
                ...

//用于区分大小写的搜索
常量结果=[];
listComponent.forEach((组件,索引)=>{
常量comp={…组件};
if(阵列isArray(组件子菜单)){
复合子菜单=复合子菜单过滤器((子菜单)=>{
返回子菜单.secTitle.includes(值);
});
如果(组件子菜单长度>0){
结果:推送(comp);
}
}
});

好的,这是解决方案

将filterComponents方法更改为

const filterComponents = (e) => {
  let value = e.target.value;
  let components = [ ...this.state.components];
  const filterData = []
  components.map(item => {
    item.subMenu.reduce((acc, cur) => {
      if (cur.secTitle === value) {
        acc.push(cur)
      }
    }, filterData)
  })
  this.setState({ filterResult: filterData });

  };
filterData将具有筛选结果


希望它有助于解决您的问题。首先,您可以找到包含所需项目的顶级项目:

格伦K回答:

let aux = listComponent.filter((component) => {
  return component.subMenu.findIndex((sub) => {
    return sub.secTitle === value;
  }) >= 0;
});
然后过滤过滤列表中的子菜单

aux = aux.map(item => {
  item.subMenu = item.subMenu.filter((component) => {
    return component.secTitle === value;
  })
  return item;
})
然后保存到你的状态

filterResult = [...aux];

this.setState({ filterResult });

您只过滤组件,因此在子菜单上再次运行过滤器以过滤子菜单:

let value = event.target.value;
let components = JSON.parse(JSON.stringify(this.state.components));

// This filter only targets the components themselves...
let filterResult = components.filter(
  component =>
    component.subMenu.findIndex(sub =>
      sub.secTitle.toLowerCase().includes(value)
    ) !== -1
);

// ...so, run the filter again, but this time filter the subMenus
for (let i = 0; i < filterResult.length; i++) {
  filterResult[i].subMenu = [ ...filterResult[i].subMenu];
  filterResult[i].subMenu = filterResult[i].subMenu.filter(
      sub =>
        sub.secTitle.toLowerCase().includes(value)           
  );
}

console.log(filterResult);

首先使用
过滤器
过滤
组件

    let filterResult = components.filter(c => c.subMenu.filter(hasRequiredSecTitle).length > 0);
然后过滤已过滤组件的
子菜单
集合:

    filterResult = filterResult.map(c => ({...c, subMenu: c.subMenu.filter(hasRequiredSecTitle)}))
因此,完整的功能将是:

filterComponents = event => {
    let value = event.target.value;
    let components = this.state.components;

    const hasRequiredSecTitle = (subMenu) => subMenu.secTitle === value;
    let filterResult = components.filter(c => c.subMenu.filter(hasRequiredSecTitle).length > 0);
    filterResult = filterResult.map(c => ({...c, subMenu: c.subMenu.filter(hasRequiredSecTitle)}))

    console.log(filterResult);

    this.setState({ filterResult });
};

这里有一些很好的答案!我想我会加入我的

这允许不区分大小写的搜索,而且非常简单

const{Component}=React;
const{render}=ReactDOM;
类应用程序扩展组件{
状态={
已筛选:[],
listComponents:this.props.listComponent | |[],
searchText:this.props.searchText | |“
};
componentDidMount=()=>
this.props.searchText&&
这个.filterComponents();
handleChange=事件=>
这个.setState({
searchText:event.target.value
}, () => {
this.state.searchText
?这是一个过滤器组件()
:this.setState({filtered:[]})
});
过滤器组件=()=>{
const{searchText,listComponents}=this.state;
const searchExp=新的RegExp(searchText,“i”);
const listCopy=JSON.parse(JSON.stringify(listComponents));
const result=listCopy.filter(项=>{
item.subMenu=item.subMenu.filter(sub=>searchExp.test(sub.secTitle));
return item.subMenu.length&&item;
});
this.setState({filtered:result})
};
render(){
const{filtered,listComponents,searchText}=this.state;
返回(
{JSON.stringify(过滤,null,2)}
);
}
}
常量listComponent=[
{
id:0,
标题:“普通”,
子菜单:[
{
图像:“”,
部门名称:“,
副标题:“
}
]
},
{
id:1,
标题:“计算”,
子菜单:[
{
图像:“require(“../../assets/images/scaling.png”),
章节:“一个comp”,
副标题:“
},
{
image:'require(“../../assets/images/ec2.png”),
章节:“两组”,
副标题:“
},
{
image:'require(“../../assets/images/lambda.png”),
章节:“三合”,
副标题:“
},
{
图像:“require(“../../assets/images/zone.png”),
章节:“四合”,
副标题:“
}
]
},
{
id:2,
标题:"第二",
子菜单:[
{
图像:“”,
部门名称:“,
副标题:“
}
]
},
{
id:3,
标题:“第三次”,
子菜单:[
{
图像:“”,
部门名称:“,
副标题:“
}
]
},
{
id:4,
标题:“第四”,
子菜单:[
{
图像:“”,
部门名称:“,
副标题:“
}
]
}
];
let索引=
呈现(索引、文档、正文)


我认为您的问题在于[index]指的是组件索引而不是子菜单索引,因此,您必须为每个子菜单迭代每个子菜单component@GlenK你能在上面的代码中显示它吗?我添加了一个代码片段和一个更简单的版本来显示我的答案中的代码应该是什么样子below@JithinVarghese我在下面添加了一个答案,请检查搜索是否正常,但问题是,
子菜单列出了所有项目。只有第一个数组被隐藏。我需要隐藏
子菜单
项。(例如:如果我搜索
一个comp