【问题标题】:filter object by two nested values通过两个嵌套值过滤对象
【发布时间】:2020-07-03 00:59:06
【问题描述】:

我遇到了过滤方法的问题。在我的页面上有一个按团队名称搜索匹配项的输入。过滤器值被存储到 React 状态。匹配对象如下所示:

[
    {
        "id": 4,
        "teamBlue": {
            "id": 36,
            "name": "nameForTeamBlue",
            "playerList": [
                {
                    [...]
                }
            ]
        },
        "teamRed": {
            "id": 37,
            "name": "nameForTeamRed",
            "playerList": [
                {
                    [...]
                }
            ]
        },
        "localDate": "2020-01-01",
        "localTime": "00:00:00",
        "referee": null,
        "commentator1": null,
        "commentator2": null,
        "streamer": null,
        "stage": {
            "id": 2,
            "name": "GROUPSTAGE"
        },
        "onLive": true,
        "finished": false
    },
]

我尝试了很多方法来按团队名称过滤比赛,例如:

      let criteria = {
        teamBlue: {
          name: this.state.filter
        },
        teamRed: {
          name: this.state.filter
        }
      };
      let filteredMatches = this.state.matches.filter(function(item) {
        for (let key in criteria) {
          if (item[key] === undefined || item[key] !== criteria[key])
            return false;
        }
        return true;
      });
      console.log(filteredMatches);

但他们都没有工作。 有没有办法过滤这些匹配项,所以当我在输入中输入“blue”时,它会显示所有团队名称包含“blue”的匹配项?

提前致谢!

【问题讨论】:

  • 您只按名称过滤,或者如果条件有键 id,那么您也想按 id 过滤?

标签: javascript arrays reactjs sorting filtering


【解决方案1】:

尝试将条件更新为:

if (!item[key] || item[key].name !== criteria[key].name)

let filteredMatches = this.state.matches.filter(function(item) {
    let flag = true;

    for (let key in criteria) {

      // update this to
      if (!item[key] || item[key].name !== criteria[key].name)
        flag = false;
    }
    return flag;
  });

【讨论】:

  • 好的,你能检查一下if里面的情况吗?并更新 json 对象和输入(我在 json 对象中没有看到任何 blue
  • let criteria = { teamBlue: { name: this.state.filter } }; 也为 teamBlue 有 "name": "nameForTeamBlue" 所以它包含“蓝色”
  • @SajibKhan 目前criteria[key]{ name: this.state.filter },,所以您正在比较总是返回false 的对象。
  • 试试这个条件:if (!item[key] || item[key].name !== criteria[key].name)
  • @Apraxia 如果一直假定name 属性,那么为什么还要将其嵌套在标准中,您可以使用criteria = { teamBlue: this.state.filter... 进行简化
【解决方案2】:

名称属性丢失:

if (key in item && item[key].name !== criteria[key].name)

【讨论】:

    【解决方案3】:

    您正在使用 === 比较对象,这将返回 false。您要么需要使用库中的深度比较方法,要么自己实现它,如下所示:

    const matches = [ {"id": 4,
        "teamBlue": {
            "id": 36,
            "name": "nameForTeamBlue",
            "playerList": []
        },
        "teamRed": {
            "id": 37,
            "name": "nameForTeamRed",
            "playerList": []
        },
    }, {"id": 4,
        "teamBlue": {
            "id": 36,
            "name": "nameForTeamBlue",
            "playerList": []
        },
        "teamRed": {
            "id": 37,
            "name": "nameForTeamRead",
            "playerList": []
        },
    }]
    
    const criteria = {
      teamBlue: {
        name: 'nameForTeamBlue',
      },
      teamRed: {
        name: 'nameForTeamRed',
      }
    }
    
    const filteredMatches = matches.filter((item) => {
      const allCriteriaMatched = Object.entries(criteria)
        .every(([key, value]) => {
          const matched = Object.entries(value).every(([criteriaKey, criteriaValue]) => {
            const itemValue = item[key][criteriaKey]
            const matched = itemValue == criteriaValue
            if (!matched) console.log('Item %s does not matched criteria %s. Item\'s value is %s, but criteria value is %s', item[key]['id'], criteriaKey, itemValue, criteriaValue, criteriaValue)
            return matched
          })
          if (!matched) return false
          return true
        }, {})
      return allCriteriaMatched
    })
    console.log(filteredMatches);

    基本上,您只需要更深入 1 级 :D 如果您的条件可以包含多个嵌套对象,那么手动执行它是没有意义的。您可以尝试映射条件以针对匹配项运行,这样您就不会在对象上使用===,而只在原语上使用。

    【讨论】:

      猜你喜欢
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 2022-12-22
      • 2020-07-28
      • 2023-01-30
      相关资源
      最近更新 更多