如何使用至少匹配一个字符串数组过滤数据?

时间:2019-02-12 14:07:35

标签: javascript reactjs search filter

我对ReactJS还是很陌生,他致力于一个显示许多不同数据的简单应用程序(称为应用程序)。我想实现一个实时的自由文本搜索过滤器。为此,我正在使用Input Element,如果值正在更改,则调用JavaScript函数。运行良好。但仅适用于一个字符串。如果要过滤更多单词,则将其作为“ AND”过滤器处理。但是我想要一个“或”过滤器。

我有这些应用程序,并使用searchString对其进行过滤。用户必须至少输入三个字符。如果用户输入两个单词和三个字符,则“ app”和“ red”,我想过滤标题中带有“ app”或“ red”字样的元素。如果最小过滤字符串之一匹配,将显示该应用。那是计划。

我尝试使用.indexOf()、. includes()并没有任何匹配,即使在文档中我也找不到像“ OR”过滤器搜索一样的东西。

这是我的代码,适用于一个字符串:

  updateSearch(event) {
    let searchString = event.target.value.toLowerCase()

    let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } ); //Only words with at least 3 chars are allowed in the array

    if (searchString.length >= 3) { //Check if the minimun amount of characters is fullfilled

      let allApps = this.props.applications;
      let apps = allApps.filter(app =>
        app.title.toLowerCase().includes(searchString)
      );
      this.props.updateApplications(apps);
    } else {
      this.clearSearch()
    } 
  }

我的输入元素:

 <Input
      id="freeTextSearch"
      className="searchInput"
      onChange={this.updateSearch.bind(this)}
      autoComplete="off"
      action={
        <Button
          id="freeTextSearchButton"
          name="search"
          icon="search"
          onClick={() => this.clearSearch()}
        />
      }
      placeholder="Search"
    />

感谢您的帮助 伊冯

答案:

谢谢' Silvio Biasiol '。您的解决方案给了我正确的提示。现在,我有一个“ OR”过滤器搜索匹配至少一个单词。现在,该函数如下所示:

updateSearch(event) {
  let searchString = event.target.value.toLowerCase()
  let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } )

  if (searchStringSplit.length >=1) { //Check if there is at least on word with tree letters

    let allApps = this.props.applications
      // If at least a word is matched return it!
    let apps = allApps.filter(app => {
      let containsAtLeastOneWord = false
        searchStringSplit.forEach(searchWord => {
            if (app.title.toLowerCase().includes(searchWord))
                containsAtLeastOneWord = true;
        })
        if (containsAtLeastOneWord)
            return app
      }
    );
    this.props.updateApplications(apps)
  } else { // user deletes manually every word
    this.clearSearch()
  } 
}

谢谢大家

3 个答案:

答案 0 :(得分:1)

如果您只想匹配至少一个单词,这很简单:)

let string = "My cool string"
let possibleStrings = [
  'My cool string', 
  'My super cool string', 
  'Another', 
  'I am lon but sadly empty',
  'Bruce Willis is better than Pokemon',
  'Another but with the word string in it',
  'Such string much wow cool']

// Split spaces
let searchString = string.toLowerCase().split(' ')
// Log the result, just wrap it in your react script
console.log(possibleStrings.filter(string => {
    let containsAtLeastOneWord = false;
    // If at least a word is matched return it!
    searchString.forEach(word => {
        if (string.toLowerCase().includes(word))
            containsAtLeastOneWord = true;
    })
    if (containsAtLeastOneWord)
        return string
}))

答案 1 :(得分:0)

您没有使用searchStringSplit数组。使用此数组,您可以执行以下操作:

const searchRegex = new RegExp(searchStringSplit.join("|"))
let apps = allApps.filter(app =>
    searchRegex.test(app.title.toLowerCase())
);

您将searchStringSplit数组连接到形式为term1|term2|term3...的正则表达式中,并使其与标题匹配。


另一种选择是使用Array.prototype.some()函数,如下所示:

let apps = allApps.filter(app => 
    searchStringSplit.some(searchString => app.title.toLowerCase().includes(searchString))
);

您适合所有应用,并针对每个应用检查其标题是否包含“某些”搜索字符串。

答案 2 :(得分:0)

尝试理解您的代码,假设searchString是“ facebook twitter youtube”

let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } );

//searchStringSplit is like [ "facebook", "twitter", "youtube" ]

//allApps is like ["TWITTER","INSTAGRAM"]
allApps.filter(app=> searchStringSplit.includes(app.toLowerCase()))

//returning me all apps in allApps that are includes in searchStringSplit
// so return ["TWITTER"]

不确定是否正是您所需要的...如果不是,请通知我,以便我更改答案...