Как отфильтровать данные с помощью массива строк, соответствующих хотя бы одной? - PullRequest
0 голосов
/ 12 февраля 2019

Я довольно новичок в ReactJS и работаю над простым приложением, которое показывает много разных данных (называемых приложениями).Я хочу реализовать живой бесплатный текстовый фильтр поиска.Для этого я использую элемент ввода, вызывая функцию JavaScript, если значение меняется.Это работает довольно хорошо.Но только для одной строки.Если я хочу отфильтровать больше слов, он обрабатывается как фильтр «И».Но мне нужен фильтр "ИЛИ".

У меня есть приложения, и я фильтрую их с помощью searchString.Пользователь должен ввести не менее трех символов.Если пользователь вводит два слова с тремя символами, например, «app» и «red», я хочу отфильтровать элементы, в названии которых есть слова «app» ИЛИ «red».Если мин.одна из строк фильтра совпадает, приложение отображается.Это план.

Я пытался использовать .indexOf (), .include (), но ничего не найдено, даже в документации я не нашел ничего похожего на поиск фильтра "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"
    />

Спасибо за помощь, Ивонна

ОТВЕТ:

СпасибоВы ' Сильвио Биасиол '.Ваше решение дало мне правильную подсказку.Теперь у меня есть фильтр поиска «ИЛИ», соответствующий хотя бы одному слову.Теперь функция выглядит так:

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 голосов
/ 12 февраля 2019

пытаясь понять ваш код, предположим, что 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"]

не уверен, что это именно то, что вам нужно ... если это не так, пожалуйста, дайте мне знать, чтобы я мог изменитьответ ...

0 голосов
/ 12 февраля 2019

Если вы просто хотите найти хотя бы одно слово, это довольно просто:)

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
}))
0 голосов
/ 12 февраля 2019

Вы не используете свой массив 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))
);

Вы подбираете все свои приложения, и для каждого приложения вы проверяете, включает ли его заголовок «некоторые» из поискастроки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...