首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ES6过滤具有多种条件的数组数据

用ES6过滤具有多种条件的数组数据
EN

Stack Overflow用户
提问于 2022-07-14 12:02:48
回答 2查看 58关注 0票数 1

我使用的是一个es6过滤器函数,它接受状态钩子的搜索字符串和值,这应该允许用户通过字符串搜索数据,然后应用过滤器属性a11yType。我可以单独通过a11yType或仅通过搜索字符串过滤数据,但无法使两者协同工作。不知道这是怎么回事:

搜索字符串挂钩(从文本输入中获取的值)

代码语言:javascript
复制
const [searchFilter, setFilter] = useState('');

可访问性字符串值(取自按钮选项的值)

代码语言:javascript
复制
const [a11yType, setA11yType] = useState('');

数据过滤和映射

代码语言:javascript
复制
data &&
    data
        .filter(
            (f) =>
                f[0].includes(searchFilter.toUpperCase()) ||
                (searchFilter === '' && f[1].type === a11yType),
        )
        .map((item, i) => {
            {
                item[1].type &&
                    rows.push(
                        createData(
                            `${item[0]}`,
                            `${item[1].type}`,
                            `${[...new Set(item[1].urls)].length}`,
                            `${item[1].urls}`,
                        ),
                    );
            }
        });
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-14 12:53:40

我不确定我完全理解你想要达到的目标,但我认为你犯了一个合乎逻辑的错误。

首先,您在语句中使用了or操作符。它检查至少其中一个条件是否为真。因此,首先检查f是否包括searchString,如果不包含,则继续到第二条语句。

其次,检查searchFilter是否为空,如果为空,则检查f1类型是否等于a11yType。

就像你描述的那样。只有在搜索短语为空时,才能通过搜索短语或a11yType进行筛选。

因此,如果您想要组合两个过滤器(检查结果包括一个searchString并有一个匹配的a11yType),只需尝试如下:

代码语言:javascript
复制
f[0].includes(searchFilter.toUpperCase())
&& // only if the search string is contained in f[0]
(a11yType === '' || f[1].type === a11yType) // a11yType is empty or the result satisfies the filter
票数 0
EN

Stack Overflow用户

发布于 2022-07-14 12:50:42

你需要对你的布尔逻辑非常具体。计算机无法猜出你的意思(不像和人说话)。

你想:

如果用户正在搜索,但没有选择类型,则

  1. 匹配搜索
  2. ,如果用户选择类型,但不匹配搜索类型
  3. ,如果用户同时搜索,选择类型匹配

因此,您的筛选功能应该是:

代码语言:javascript
复制
(f) =>
    (a11yType === '' && f[0].includes(searchFilter.toUpperCase())) ||
    (searchFilter === '' && f[1].type === a11yType) ||
    (f[0].includes(searchFilter.toUpperCase()) && f[1].type === a11yType)

在短期内,这将解决你的问题。

但是,请注意,随着添加的条件越多,这将很快变得无法管理。如果您添加了另一个选项:“类别”,您的代码将变得非常大:

代码语言:javascript
复制
(f) =>
    (category === '' && a11yType === '' && f[0].includes(searchFilter.toUpperCase())) ||
    (category === '' && searchFilter === '' && f[1].type === a11yType) ||
    (category === '' && f[0].includes(searchFilter.toUpperCase()) && f[1].type === a11yType) ||
    (a11yType === '' && searchFilter === '' && f[1].category === category) ||
    (searchFilter === '' && f[1].type === a11yType &&  f[1].category === category) ||
    (f[0].includes(searchFilter.toUpperCase()) && f[1].type === a11yType  &&  f[1].category === category)

更别提它变得很难读了。我不确定仅仅查看上面的函数是否是格式良好的,还是语法错误--如果逻辑是正确的,更不用说了!

对于这种逻辑,有一点要注意的是,如果条件是空的,那么我们就忽略这个条件。对于.filter()函数,忽略一个条件意味着我们总是返回true

重构代码,我们可以执行以下操作:

代码语言:javascript
复制
(f) => {
    const searchCond = searchFilter === '' || f[0].includes(searchFilter.toUpperCase()));

    const typeCond = a11yType === '' || f[1].type === a11yType;

    return searchCond && typeCond;
}

基本上,我们将逻辑从或和(乘积之和)转换为和或或(和积)。这样我们就可以避免两次输入条件。注意,在上面重构的代码中,我们只检查f[1].type === a11yType一次,而不需要为匹配搜索和类型的第三种情况重新键入它。

通过这种方式,添加另一个选项只需要再添加一个条件:

代码语言:javascript
复制
(f) => {
    const searchCond = searchFilter === '' || f[0].includes(searchFilter.toUpperCase()));

    const typeCond = a11yType === '' || f[1].type === a11yType;

    const categoryCond = category === '' || f[1].category === category;

    return searchCond && typeCond && categoryCond;
}

当然,你也可以用你喜欢的紧凑的形式写这个:

代码语言:javascript
复制
(f) => 
    (searchFilter === '' || f[0].includes(searchFilter.toUpperCase()))) &&
    (a11yType === '' || f[1].type === a11yType) &&;
    (category === '' || f[1].category === category);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72980172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档