按字词开头过滤结果

问题描述 投票:1回答:5

我正在研究ReactJS课程中的一个项目,并且遇到了一个问题。我想搜索结果并根据单词的BEGINNING进行过滤,而不仅仅是结果中任何位置存在的字符串。

例如,在联系人列表中,键入“r”可能会返回Richard,Aaron和Barbara,因为它们都包含“r”。如何制作它以便从单词的开头开始过滤,就像在字典中一样?

我目前正在使用受控组件过滤数组中的结果,以动态搜索和过滤结果。以下是截至目前的相关摘录:

filterResults = (venueFilter) => {
  let filteredVenues = this.state.venues
  filteredVenues = filteredVenues.filter((venue) => {
    let venueData = venue.name.toLowerCase();
    return venueData.indexOf(venueFilter.toLowerCase()) !== -1
  })
  this.setState({
    filteredVenues
  })
}

该项目正在呼叫我附近的餐馆。但是输入“r”会带来很多东西,因为它是一个普通的字母,因为“餐厅”以R开头。打字“M”带来了日本餐厅“MIKADO”(有用/良好的用户体验),但也返回“暹罗泰语“和”Stadtmauer“(不是特别有帮助/糟糕的用户体验)。

如何从单词的开头进行过滤?

javascript arrays reactjs sorting servlet-filters
5个回答
1
投票

使用startsWith而不是indexOf

filteredVenues = filteredVenues.filter(venue =>
  venue.name.toLowerCase().startsWith(venueFilter.toLowerCase())
)

0
投票

您可以使用正则表达式来检查字符串是否符合要求

const data = [
 'MIKADO',
 'Siam Thai',
 'Stadtmauer',
 'Another',
 'Ane',
 'Anna',
];

// What the user typed for it's search
const search = 's';

// Build a regex using the searched string
// i for case insensitive
const regex = new RegExp(`^${search}`, 'i');

const filteredData = data.filter(x => regex.test(x));

console.log(filteredData);

0
投票

你需要一个正则表达式,它可以通过\b字边界标志锚定到一个单词的开头。

filteredVenues = filteredVenues.filter((venue) => {
    return new RegExp('/\\b'+venueFilter+'/', 'i').test(venue.name);
})

注意我们也不需要将字符串协调为小写,因为通过使用i不区分大小写的标志,它将匹配任何一种情况。

旁注:这是使用“动态”正则表达式的示例,该表达式是为了考虑变量而构建的。这对于REGEX文字来说是不可能的,即一个不是用new RegExp构造函数而是用/pattern/创建的。


0
投票

我认为这个教程可能对你有所帮助:

https://www.w3schools.com/howto/howto_js_autocomplete.asp

它有关于过滤搜索的代码部分,可以执行您想要的操作(我猜)。

    inp.addEventListener("input", function(e) {
      var a, b, i, val = this.value;
      /*close any already open lists of autocompleted values*/
      closeAllLists();
      if (!val) { return false;}
      currentFocus = -1;
      /*create a DIV element that will contain the items (values):*/
      a = document.createElement("DIV");
      a.setAttribute("id", this.id + "autocomplete-list");
      a.setAttribute("class", "autocomplete-items");
      /*append the DIV element as a child of the autocomplete container:*/
      this.parentNode.appendChild(a);
      /*for each item in the array...*/
      for (i = 0; i < arr.length; i++) {
        /*check if the item starts with the same letters as the text field value:*/
        if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
          /*create a DIV element for each matching element:*/
          b = document.createElement("DIV");
          /*make the matching letters bold:*/
          b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
          b.innerHTML += arr[i].substr(val.length);
          /*insert a input field that will hold the current array item's value:*/
          b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
          /*execute a function when someone clicks on the item value (DIV element):*/
              b.addEventListener("click", function(e) {
              /*insert the value for the autocomplete text field:*/
              inp.value = this.getElementsByTagName("input")[0].value;
              /*close the list of autocompleted values,
              (or any other open lists of autocompleted values:*/
              closeAllLists();
          });
          a.appendChild(b);
        }
      }
  });

0
投票

第一次出现排序怎么样?通过这一点,在开头匹配的那些首先出现:

 const result = venues
   .map(venue => ({ venue, score: venue.name.indexOf(search) }))
   .filter(it => it.score !== -1)
   .sort((a, b) => a.score - b.score)
   .map(it => it.venue);
© www.soinside.com 2019 - 2024. All rights reserved.