admin管理员组

文章数量:1401407

I have an array of elements (let's say a list of fitness trainings).

I have a search bar, and I would like to create a search feature to find a specific training.

I know how to filter the array to:

  1. Keep trainings where name start with string typed in the search bar

    array = array.filter(function(item) {
       return item.name.toLowerCase().startsWith(searchFilter.toLowerCase());
    });
    

Exemple: Search = "El"...

Results -> ["Elizabeth", "Elisa"]

Results not fetched -> ["Open Elios"]

  1. Keep trainings where name contains string typed in the search bar

    array = _.filter(array, function(item) {
       return _.includes(item.name.toLowerCase(), searchFilter.toLowerCase());
    });
    

Exemple: Search = "El"...

Results -> ["Elizabeth", "Open Elios", "Camel"]

But it's not what I would like:

  1. Keep training where name contains words starting with string typed in the search bar

Exemple: Search = "El"...

Results -> ["Elizabeth", "Open Elios"]

Results not fetched -> ["Camel"]

I have an array of elements (let's say a list of fitness trainings).

I have a search bar, and I would like to create a search feature to find a specific training.

I know how to filter the array to:

  1. Keep trainings where name start with string typed in the search bar

    array = array.filter(function(item) {
       return item.name.toLowerCase().startsWith(searchFilter.toLowerCase());
    });
    

Exemple: Search = "El"...

Results -> ["Elizabeth", "Elisa"]

Results not fetched -> ["Open Elios"]

  1. Keep trainings where name contains string typed in the search bar

    array = _.filter(array, function(item) {
       return _.includes(item.name.toLowerCase(), searchFilter.toLowerCase());
    });
    

Exemple: Search = "El"...

Results -> ["Elizabeth", "Open Elios", "Camel"]

But it's not what I would like:

  1. Keep training where name contains words starting with string typed in the search bar

Exemple: Search = "El"...

Results -> ["Elizabeth", "Open Elios"]

Results not fetched -> ["Camel"]

Share Improve this question edited May 25, 2019 at 13:05 adiga 35.3k9 gold badges65 silver badges87 bronze badges asked May 25, 2019 at 13:00 KevinBKevinB 2,4844 gold badges28 silver badges55 bronze badges 5
  • What is the difference between the first and the thrid? – adiga Commented May 25, 2019 at 13:04
  • @adiga first: 1st = if a string contains multiple words, only the first one is concerned by the search. 3rd = if a string contains multiple words, all the words are concerned by the search – KevinB Commented May 25, 2019 at 13:06
  • @KevinB you want values like hello-el to be included in filtered result ? – Code Maniac Commented May 25, 2019 at 13:14
  • Not especially, only with space is great – KevinB Commented May 25, 2019 at 13:19
  • @CodeManiac Although it's not very clear, but I think the OP wants as he mentions name contains words starting with string typed in the search bar. – nice_dev Commented May 25, 2019 at 13:24
Add a ment  | 

4 Answers 4

Reset to default 4

You can use regex for that, something like:

const result = ["Elizabeth", "Open Elios", "Camel"].filter(v => /\bel/i.test(v));
console.log(result);

The important part is \b which means word boundary, basically this expression /bel is testing if the value contains something that starts with a word boundary and is fallowed by el.

Here is a plete example that constructs the regex from a string:

const array = ["Elizabeth", "Open Elios", "Camel"];
const searchFilter = 'El';
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

const result = array.filter(value => new RegExp(`\\b${escapeRegExp(searchFilter)}`, "i").test(value));

console.log(result);

You could create a dynamic regex with a word boundary \b using RegExp constructor

function filter(arr, word) {
  const regex = new RegExp(`\\b${word}`, 'i');
  return arr.filter(n => regex.test(n))
}

console.log(filter(["Elizabeth", "Elisa", "Open Elios", "Camel"], "El"))

Apart form regex, you could also apply filter twice with the last one returning a boolean value for the filter of the current string to be included.

var search_string = 'eli';
search_string = search_string.toLowerCase();
const arr = ["Elizabeth", "Open Elios", "Camel"];
const result = arr.filter(value => value.split(' ').filter(token => token.toLowerCase().startsWith(search_string)).length > 0);
console.log(result);

Update:

As suggested by @Titus in the ments, you can also use some() method to filter data which would immediately return true if it finds a token which starts with your search string, instead of collecting all tokens in a filter that would start with your search string.

var search_string = 'eli';
search_string = search_string.toLowerCase();
const arr = ["Elizabeth", "Open Elios", "Camel"];
const result = arr.filter(value => value.split(' ').some(token => token.toLowerCase().startsWith(search_string)));
console.log(result);

You can use regex to build a dynamic pattern based on value

(?:^|[ ])${value}
  • (?:^|[ ]) - Match start of string or space
  • ${value} - dynamic value ing from search bar

let search = (value) => {
  const reg = `(?:^|[ ])${value}`
  const regex = new RegExp(reg,'gi')
  const result = ["Elizabeth", "Open Elios", "Camel"].filter(v => regex.test(v));
  return result
}

console.log(search('el'));

本文标签: javascriptLodashSearch if String contains a word that start withStack Overflow