Home > OS >  Filter array based on each letter in the search string
Filter array based on each letter in the search string

Time:09-02

Take the code below which works fine:

function Test() {
  const txt = 'a'
  const fruit = [
    { name: 'apple' },
    { name: 'orange' },
    { name: 'kiwi' },
    { name: 'banana' },
    { name: 'lemon' },
  ]

  return (
    <FlatList
      data={fruit.filter((item) => String(item.name).includes(txt))}
      renderItem={({ item }) => <Text>{item.name}</Text>}
    />
  )
}

export default Test

The search string (txt) is a so the output would be:

apple
orange
banana

So far so good, now I want to be able to type for example ae and get all the items in the array that include both a and e in any order, not just ae together. here is the expected result for const txt = 'ae':

apple
orange

CodePudding user response:

You can do it like this

  function Test() {
      const txt = 'a'
      const fruit = [
        { name: 'apple' },
        { name: 'orange' },
        { name: 'kiwi' },
        { name: 'banana' },
        { name: 'lemon' },
      ]


const searchFinal = () => {
        const newSplitSearch = txt.split("");
        const finalArray = []
        fruit.map((data) => {
    
          const nameData = data.name;
          let shouldBeAdded = true;
    
          for (let i = 0; i < newSplitSearch.length; i  ) {
            if (nameData.includes(newSplitSearch[i])) {
    
            } else {
              shouldBeAdded = false;
            }
          }
    
          if (shouldBeAdded) {
            finalArray.push(data)
          }
    
        })
    
        return finalArray
      }
    
      return (
        <FlatList
          data={searchFinal()}
          renderItem={({ item }) => <Text>{item.name}</Text>}
        />
      )
    }
    
    export default Test

Hope it helps :)

CodePudding user response:

One way is to split the word characters and then on the filter check all of them with array.prototype.every

const txt = 'ae'
const fruit = [
    { name: 'apple' },
    { name: 'orange' },
    { name: 'kiwi' },
    { name: 'banana' },
    { name: 'lemon' },
]

const search = (arr, str) => {
   const chars = str.split('');
   return arr.filter(
      item => chars.every(char => item.name.includes(char)) );
}

console.log(search(fruit, txt) )

CodePudding user response:

Unfortunately the .includes() method of the String object just accepts a string-type parameter to search for.

What you can do however is using a regular expression instead.

Most basically this would be:

console.log("apple".match(/[a|e]/g));

The above would look for the letters a and e and return an array with the results found for apple ["a", "e"]. Problem is it would also return something if there is three times a and no e like in banana.

To overcome this issue we need to clean the returned array from duplicates first and afterwards check if the number of elements is at least the number of unique letters we want to look for - which is 2 in case of a and e.

Here's an example:

const fruit = [{
    name: 'apple'
  },
  {
    name: 'orange'
  },
  {
    name: 'kiwi'
  },
  {
    name: 'banana'
  },
  {
    name: 'lemon'
  },
]
let txt = "ae";
let regex = new RegExp("["   txt.split("").join("|")   "]", "g");
fruit.forEach(item => {
  console.log(item.name, [...new Set(item.name.match(regex))].length >= txt.length);
})

  • Related