简体   繁体   中英

how to filter strings in array?

I was trying to search for function. This function checks the nested array, which has multiple strings, then returns if the array has a search word.

The data structure of the array

[
  {
   name:'aa',
   searchWords:['aa','ab','bc'] <- I want to use this array for search
  },
  {
   name:'bb',
   searchWords:['bb','bc','de'] <- I want to use this array for search
  },
...
]

I tried to use indexOf function.
However, I couldn't display any components with this code below.
But I changed target value from item.searchWords to item.name in the code. it worked.

HTML
<div className="itemWrapper">
     {filterItems.map((item, idx) => (
            <Item key={idx} {...item} id={idx} list={list} />
      ))}
</div>    


Js
const filterItems = list.filter(
      (item) => item.searchWords.indexOf(searchWord) !== -1,
    );

My desired result is that search result update in realtime.
For instance with the same data structure above, when the user searches 'a', searchWords 'aa' and 'ab' returns true for displaying the item,

Thank you so much for your help.

You need to loop over the searchWords array to find if it matches the search word. This one will work
const filterItems = list.filter( (item) => item.searchWords.filter((myWord) => myWord.indexOf(searchWord)>-1) );

You can try with find() and includes() on name property of the object and finally filter() .

Demo:

 var list = [ { name:'aa', searchWords:['aa','ab','bc'] }, { name:'bb', searchWords:['bb','bc','de'] } ] document.getElementById('searchWord').addEventListener('input', function(){ console.clear(); var filterItems = list.find(item => item.name.includes(this.value)); filterItems = filterItems? filterItems.searchWords: []; filterItems = filterItems.filter(i => i.includes(this.value)); console.log(filterItems); });
 <input id="searchWord"/>

You can use array#reduce and filter searchWords array using the array#filter by checking the search words.

 const dataSource = [{ name: 'aa', searchWords: ['aa', 'ab', 'bc'] }, { name: 'bb', searchWords: ['bb', 'bc', 'de'] } ], searchWord = 'a', result = dataSource.reduce((res, {name, searchWords}) => { let matched = searchWords.filter(word => word.includes(searchWord)); if(matched.length) { res.push({name, searchWords: matched}); } return res; },[]) console.log(result);

It is because, how indexOf works, with array and strings .

let's say syntax of indexOf is

operatedItem.indexOf(searchedItem);

Here, in your case

{
   name:'bb',
   searchWords:['bb','bc','de']
}

name is a string ,

and searchWords is an array .

When you perform:

name.indexOf("b"); //0

name.indexOf("bb"); //0

name.indexOf("a"); //-1

It will check if the searchedItem exists anywhere in operatedItem .

 let str = "aa ab a bb"; console.log(str.indexOf("a")); //0 console.log(str.indexOf("aa")); //0 console.log(str.indexOf("ab")); //3 console.log(str.indexOf("b")); //4 console.log(str.indexOf("c")); //-1 console.log(str.indexOf("aaa")); //-1

And when indexOf is used with array ,

it checks if a searchedItem exists in the operatedItem array, it will not go for substring search.

 let arr = ["aa", "ab", "a", "bb"]; console.log(arr.indexOf("a")); //2 console.log(arr.indexOf("aa")); //0 console.log(arr.indexOf("ab")); //1 console.log(arr.indexOf("b")); //-1 console.log(arr.indexOf("c")); //-1 console.log(arr.indexOf("aaa")); //-1

The issue with the code is that its trying to find if the array contains a word when you use indexOf. Eg: When you search for 'a', the code checks is there is any word 'a' in the array and not any word containing letter 'a'.

You need to change the JS part to:

Js

 const list = [{ name: 'aa', searchWords: ['aa', 'ab', 'bc'] }, { name: 'bb', searchWords: ['bb', 'bc', 'de'] } ]; let searchWord = "a"; const filterItems = list.filter( (item) => item.searchWords.filter(word => word.includes(searchWord)).length > 0 ); document.getElementById('result').innerHTML = JSON.stringify(filterItems);
 <p id="result"> </>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM