当前位置: 代码迷 >> JavaScript >> 基于Javascript中的过滤器数组过滤数组
  详细解决方案

基于Javascript中的过滤器数组过滤数组

热度:100   发布时间:2023-06-13 12:20:30.0

我有一组用户和一系列过滤器。

我需要根据过滤器数组过滤用户,但是当我这样做时,它将过滤一个阵列而不是其他阵列

我的过滤器对象如下所示:

filters: {
  levels: [],
  locations: ['Laois'],
  subjects: ['Art']
}

我的用户看起来像这样:

const users = [
  {
    email: 'example1@gmail.com',
    levels: ['Ordinary'],
    location: 'Laois',
    subjects: ['Art', 'German']
  },
  {
    email: 'example2@gmail.com',
    levels: ['Higher', 'Ordinary'],
    location: 'Laois',
    subjects: ['English', 'German']
  }
]

基于上面的过滤器,一旦过滤,用户应该只有一个,因为它包含'Art'和'Laois':

[{
    email: 'example1@gmail.com',
    levels: ['Ordinary'],
    location: 'Laois',
    subjects: ['Art', 'German']
  },
]

但我仍然得到两个用户:

编辑我的代码:

applyFilter = (visable) => {
    let { filters, users } = this.state;
    const { subjects, locations, levels } = filters;


    let filteredUsers = [];
    const filteredData = users.filter((user) =>
      user.subjects.some(subject => subjects.includes(subject)) ||
      locations.some(location => location === user.location) ||
      user.levels.some(level => levels.includes(level))
    );

    console.log(filteredData)


    if (!subjects.length && !locations.length && !levels.length) {
      filteredUsers = users;
    } else {
      filteredUsers = filteredData;
    }

    this.setState({
      filterModalVisible: visable,
      filteredResults: filteredUsers.length >= 0 ? filteredUsers : [],
    });
  }

您可以使用filterevery方法执行此操作,方法是检查过滤器值中的每个元素是否都存在于具有相同键的用户值中。

 const filters = {"levels":[],"locations":["Laois"],"subjects":["Art"]} const users = [{"email":"example1@gmail.com","levels":["Ordinary"],"locations":"Laois","subjects":["Art","German"]},{"email":"example2@gmail.com","levels":["Higher","Ordinary"],"locations":"Laois","subjects":["English","German"]}] const res = users.filter(user => { return Object.entries(filters) .every(([key, value]) => { if (Array.isArray(value)) { return value.every(filter => { return user[key] && user[key].includes(filter) }) } else { return user[key] == value } }) }) console.log(res) 

您可以尝试使用filter()

 const filters = { levels: [], locations: ['Laois'], subjects: ['Art'] } const users = [ { email: 'example1@gmail.com', levels: ['Ordinary'], location: 'Laois', subjects: ['Art', 'German'] }, { email: 'example2@gmail.com', levels: ['Higher', 'Ordinary'], location: 'Laois', subjects: ['English', 'German'] } ] var res = users.filter(info => info.location==filters.locations[0] && info.subjects.includes(filters.subjects[0])); console.log(res); 

您可以使用 , 和为任何过滤器密钥设置通用解决方案

  • 使用filter根据所有过滤条件验证每个条目
  • 如果过滤条件具有空列表,请继续检查下一个条件
  • 对于位置 ,由于filter key key in objectkey in object 不同 ,请为我们检查位置数组中的位置添加特定检查
  • 对于其他字段,检查数组中是否存在过滤器值中存在的至少1个条目。 如果存在值,请继续检查下一个条件。
  • 条件检查后,确认条目是否有效,如果没有中断循环并返回false

 let filters = {levels: [],locations: ['Laois'],subjects: ['Art']}; let users = [{email: 'example1@gmail.com',levels: ['Ordinary'],location: 'Laois',subjects: ['Art', 'German']},{email: 'example2@gmail.com',levels: ['Higher', 'Ordinary'],location: 'Laois',subjects: ['English', 'German']}]; users = users.filter(v => { let response = true; for (let filter in filters) { if(!filters[filter].length) continue; if(filter === "locations") { response = response && filters.locations.includes(v.location) } else response = response && v[filter].some(f => filters[filter].includes(f)); if(!response) break; } return response; }); console.log(users); 

在过滤器内使用过滤器

 const filters = { levels: [], locations: ['Laois'], subjects: ['Art'] } const users = [ { email: 'example1@gmail.com', levels: ['Ordinary'], location: 'Laois', subjects: ['Art', 'German'] }, { email: 'example2@gmail.com', levels: ['Higher', 'Ordinary'], location: 'Laois', subjects: ['English', 'German'] } ] console.log(users.filter((e) => { var arr = e.subjects.filter((x) => filters.subjects.includes(x)) if (arr.length > 0 && filters.locations.includes(e.location)) return e })) 

  1. 您需要使用&&而不是|| 如果你想匹配所有条件
  2. 根据您的要求,如果过滤器数组为空,则需要所有这些匹配,因此您可以绕过该情况的检查

 applyFilter = (visable) => { let { filters, users } = this.state; const { subjects, locations, levels } = filters; const filteredResults = users.filter((user) => (!subjects.length || user.subjects.some(subject => subjects.includes(subject))) && (!locations.length || locations.some(location => location === user.location)) && (!levels.length || user.levels.some(level => levels.includes(level))) ); this.setState({ filterModalVisible: visable, filteredResults }); } 

  相关解决方案