javascript - 基于多个滤波器的滤波器阵列

标签 javascript arrays reactjs filter

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

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

我允许用户选择他们想要使用的过滤器并将其存储在 useState 的对象中。我还跟踪过滤器是否处于事件状态。

const [filter, setFilter] = useState({active: false})

用户选择过滤器的过滤器对象将如下所示:

filter: {active: true, customerEmail: '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="53393c3b3d373c3613343e323a3f7d303c3e" rel="noreferrer noopener nofollow">[email protected]</a>', status: 'open'}

当用户将此过滤器应用于表时,当过滤器发生更改时,我会在 useEffect 中调用名为 updateFilter() 的函数。然后,这会将过滤后的数组设置为状态,然后在 return 中迭代。

const updateFilter = () => {
    const filteredInvoices = invoices.filter((inv) => {
        const emailMatch = filter.customerEmail && inv.customerEmail.toLowerCase().includes(filter.customerEmail.toLowerCase())
        const statusMatch = inv.status === filter.status
        return emailMatch || statusMatch
    })
    setListToRender(filteredInvoices)
}

useEffect(() => {
    if (filter.active) {
        updateFilter()
    }

}, [filter])

正在过滤的状态是一个对象数组。

如何根据添加到过滤器对象中的多个条件进行过滤?

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

例如 - [email protected]有 10 张发票 - 3 张未结发票、4 张已付款发票和 3 张作废发票。如果过滤器对象如下所示:

如何过滤以仅显示该客户的未结发票。

预先感谢您的任何建议!

最佳答案

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

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: ['<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8de7e2e5e3cde9e2e8a3eee2e0" rel="noreferrer noopener nofollow">[email protected]</a>', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5f3c37301f322a32323e713c3032" rel="noreferrer noopener nofollow">[email protected]</a>']
};

这种方法比简单的键/值匹配方法具有更多细微差别,并且可以让您更深入地自定义过滤器

关于javascript - 基于多个滤波器的滤波器阵列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64084176/

相关文章:

javascript - dojo.empty()/domConstruct.empty() 到底做了什么

javascript - 在 JavaScript 对象中按值查找

javascript - 如何提取苹果10亿倒计时?

javascript - 将一个数组与另一个数组值进行比较

javascript:为数组中的每个字符串创建自动子字符串

javaScriptstartsWith 方法给出错误

javascript - 在单个函数中设置状态两次 - ReactJS

javascript - $scope.name.push() 不工作

javascript - 如何检查负责SSR的google云功能是否运行?

reactjs - 更改react-day-picker DayPickerInput组件中的语言