Javascript 基于多滤波器的滤波器阵列

Javascript 基于多滤波器的滤波器阵列,javascript,arrays,reactjs,filter,Javascript,Arrays,Reactjs,Filter,我有一个表,我希望能够应用多个过滤器。我当前的代码将通过电子邮件或状态进行过滤,但我希望它同时进行过滤,以便用户可以优化结果 我尝试在filteredInvoices变量中添加&&而不是| | 我允许用户选择他们想要使用的过滤器,并将其存储在useState中的对象中。如果过滤器处于活动或非活动状态,我也会跟踪状态 const [filter, setFilter] = useState({active: false}) 用户选择其过滤器的过滤器对象如下所示: filter: {active:

我有一个表,我希望能够应用多个过滤器。我当前的代码将通过电子邮件或状态进行过滤,但我希望它同时进行过滤,以便用户可以优化结果

我尝试在filteredInvoices变量中添加&&而不是| |

我允许用户选择他们想要使用的过滤器,并将其存储在useState中的对象中。如果过滤器处于活动或非活动状态,我也会跟踪状态

const [filter, setFilter] = useState({active: false})
用户选择其过滤器的过滤器对象如下所示:

filter: {active: true, customerEmail: 'johndoe@gmail.com', status: 'open'}
当用户将此筛选器应用于表时,我会在更改筛选器时调用名为updateFilter in Useffect的函数。然后,当在返回中迭代时,这会将过滤后的数组设置为state

正在筛选的状态是一个对象数组

如何通过添加到筛选器对象中的多个条件进行筛选

是否有一个通用的设计允许我向filter对象添加额外的过滤器,并且它也可以工作

例如—johndoe@gmail.com有10张发票-3张未结,4张已付款,3张作废。如果过滤器对象如下所示:

filter: {active: true, customerEmail: 'johndoe@gmail.com', status: 'open'}
如何筛选以仅显示该客户的未结发票

提前感谢您的建议

概述 过滤通常作为对后端服务的API请求更有效,但在前端完全可行。我还认为,您希望这种情况发生在某个事件上,而不是在useEffect内。也就是说,这里有几个过滤选项

选择1 为发票对象上的每个可筛选属性添加条件

const filteredInvoices = invoices.filter((inv) => {
  const isEmailMatch = inv.customerEmail.toLowerCase() === filter.customerEmail.toLowerCase();
  const isStatusMatch = inv.status === filter.status;

  // Add other matches here.

  return isEmailMatch && isStatusMatch;
 });
选择2 这将需要从过滤器状态中提取状态。在我看来,这个解决方案更具可扩展性

const [active, setActive] = useState(false); // Extracting active.
const [filter, setFilter] = useState({});

const updateFilter = () => {
  const filteredInvoices = invoices.filter((item) => {
    for (const key in filter) {
      if (item[key] === undefined || item[key] !== filter[key])
        return false;
    }
    return true;
  });
};

useEffect(() => {
  if (active) updateFilter();
}, [filter]);
概述 过滤通常作为对后端服务的API请求更有效,但在前端完全可行。我还认为,您希望这种情况发生在某个事件上,而不是在useEffect内。也就是说,这里有几个过滤选项

选择1 为发票对象上的每个可筛选属性添加条件

const filteredInvoices = invoices.filter((inv) => {
  const isEmailMatch = inv.customerEmail.toLowerCase() === filter.customerEmail.toLowerCase();
  const isStatusMatch = inv.status === filter.status;

  // Add other matches here.

  return isEmailMatch && isStatusMatch;
 });
选择2 这将需要从过滤器状态中提取状态。在我看来,这个解决方案更具可扩展性

const [active, setActive] = useState(false); // Extracting active.
const [filter, setFilter] = useState({});

const updateFilter = () => {
  const filteredInvoices = invoices.filter((item) => {
    for (const key in filter) {
      if (item[key] === undefined || item[key] !== filter[key])
        return false;
    }
    return true;
  });
};

useEffect(() => {
  if (active) updateFilter();
}, [filter]);
可以使用filter和every array方法进行筛选

常量发票=[ {active:false,CustomerMail:'joedoe@gmail.com,状态:'已支付'}, {active:false,CustomerMail:'sam@gmail.com,状态:'已支付'}, {active:true,CustomerMail:'michael@gmail.com,状态:'void'}, {active:true,CustomerMail:'adam@gmail.com,状态:'已支付'}, {active:true,CustomerMail:'johndoe@gmail.com,状态:'打开'} ] 常量筛选器={active:true,CustomerMail:'johndoe@gmail.com,状态:'打开'} 常量selectedFilterKeys=Object.keysfilter const filteredInvoices=invoices.filterinvoice=>selectedFilterKeys.everykey=> 过滤器[键]==发票[键] console.logfilteredinsvoices,filteredinsvoices您可以使用filter和每个数组方法进行过滤

常量发票=[ {active:false,CustomerMail:'joedoe@gmail.com,状态:'已支付'}, {active:false,CustomerMail:'sam@gmail.com,状态:'已支付'}, {active:true,CustomerMail:'michael@gmail.com,状态:'void'}, {active:true,CustomerMail:'adam@gmail.com,状态:'已支付'}, {active:true,CustomerMail:'johndoe@gmail.com,状态:'打开'} ] 常量筛选器={active:true,CustomerMail:'johndoe@gmail.com,状态:'打开'} 常量selectedFilterKeys=Object.keysfilter const filteredInvoices=invoices.filterinvoice=>selectedFilterKeys.everykey=> 过滤器[键]==发票[键]
console.logfilteredInvoices,filteredInvoices由于您不仅希望能够匹配特定的键值对,还可能需要像将电子邮件转换为小写一样在过滤之前对值进行预处理,因此通用方法可能最适合您。你可以吃这样的东西

const updateFilter = () => {
    const filteredInvoices = invoices.filter(invoice => {
    let validInvoice = true;
    
    for (const [key, value] of Object.entries(filter)) {
      if (Array.isArray(value)) {
        if (!value.includes(invoice[key])) {
          validInvoice = false;
        }
      }
      else if (typeof value === 'function') {
        if (!value(invoice[key])) {
          validInvoice = false;
        }
      }
      else {
        if (value !== invoice[key]) validInvoice = false;
      }
    }
    
    return validInvoice;
  });
  
  setListToRender(filteredInvoices)
}
使用这种方法,您可以拥有一个包含原始值、函数或数组的过滤器。像这样:

const filter = {
    // This will check if the invoice 'active' property is true
    active: true,
    // This will check that the status is NOT equal to pending
    status: (status) => status !== 'pending',
    // This will check if the email matches ANY of these values
    email: ['john@doe.com', 'cho@mumma.com']
};

与简单的键/值匹配方法相比,这种方法允许更多的细微差别,并且可以让您更深入地定制过滤器

,因为您不仅希望能够匹配特定的键-值对,还可能需要像将电子邮件转换为小写字母一样,在过滤之前对值进行预处理,那么,通用方法可能最适合您。你可以吃这样的东西

const updateFilter = () => {
    const filteredInvoices = invoices.filter(invoice => {
    let validInvoice = true;
    
    for (const [key, value] of Object.entries(filter)) {
      if (Array.isArray(value)) {
        if (!value.includes(invoice[key])) {
          validInvoice = false;
        }
      }
      else if (typeof value === 'function') {
        if (!value(invoice[key])) {
          validInvoice = false;
        }
      }
      else {
        if (value !== invoice[key]) validInvoice = false;
      }
    }
    
    return validInvoice;
  });
  
  setListToRender(filteredInvoices)
}
使用这种方法,您可以拥有一个包含原始值、函数或数组的过滤器。像这样:

const filter = {
    // This will check if the invoice 'active' property is true
    active: true,
    // This will check that the status is NOT equal to pending
    status: (status) => status !== 'pending',
    // This will check if the email matches ANY of these values
    email: ['john@doe.com', 'cho@mumma.com']
};
与简单的键/值匹配方法相比,这种方法允许更多细微差别,并且可以让您更深入地定制过滤器