Home > OS >  How to filter the strings without using regex?
How to filter the strings without using regex?

Time:07-01

I'm filtering the array of strings with a matching character. The task is to get the strings with the character "o" from first part of the word.

const fruits =["apple orange", "Orange", "banana", "banana", "apple"]

const character = "o"

const filterdFruits = fruits.filter((item) => item.charAt(0).toLowerCase() === character.toLowerCase())

console.log(filterdFruits)

The above logic will return the character matching with first letter of the string, which is Orange. But what I'm expecting here is to include Orange, apple orange as part my answer. There is reason why I want Orange to be in first place as it is an exact match and, while, apple orange is also a match but not an exact match. I'm reluctant to use regex here as I have the tendency to go wrong. Happy to get some directions :)

CodePudding user response:

A small change to split each input on space(s) and to check each resulting word for a first letter of 'o' should work:

const fruits = ["apple orange", "Orange", "banana", "banana", "apple", 'plum kiwi Orange']

const character = "o"

const filterdFruits = fruits.filter((item) => { 
    return item.split(/\s /).some(word => { 
        return word.charAt(0).toLowerCase() === character.toLowerCase()
    })
});

console.log(filterdFruits)
.as-console-wrapper { max-height: 100% !important; }

CodePudding user response:

You can use this Regexp /\b[o]/gi to identify words starting with o

Important: this will match " Orange"

const fruits =["apple orange", "Orange", "banana", "banana", "apple"]
const filterdFruits = fruits.filter((item) => /\b[o]/i.test(item))

console.log(filterdFruits)

CodePudding user response:

Depending on your strings in your array, using a regular expression (I know you said you were reluctant to use them as you feel you may go wrong, but I thought I'd show some examples) may be enough. Here we match on a word boundary \b, followed by an o:

const fruits =["apple orange", "Orange", "banana", "banana", "apple"]
const filterdFruits = fruits.filter(item => /\bo/i.test(item))
console.log(filterdFruits)

The word boundary is zero-length, and matches the following:

  • Before the first character in the string, if the first character is a word character.
  • After the last character in the string, if the last character is a word character.
  • Between two characters in the string, where one is a word character and the other is not a word character.

The first and last options allow us to match both "Orange" and "apple orange". Note that the word boundary matches between non-word characters, so apple $orange would also be a valid match. We can change the regex a little to fix this case, where we only match words that start with o (^o) or (|) have an o following a whitespace character \so that is not preceded by ((?<!)) the beginning of the string ^:

const fruits =["apple orange", "Orange", "banana", "banana", "apple"]
const filterdFruits = fruits.filter(item => /^o|(?<!^)\so/i.test(item))
console.log(filterdFruits)

In both expressions above, the /i means do a case-insensitive match. To make the above expressions dynamic so that they use the character, with can use the RegExp constructor, eg:

const fruits = ["apple orange", "Orange", "banana", "banana", "apple"];
const character = "o";
const filterdFruits = fruits.filter(item => new RegExp(String.raw`\b${character}`, 'i').test(item))
console.log(filterdFruits)

If character is user-supplied, you need to start worrying about escaping your character string so that regex can't be inserted as a value. There aren't any native ways to escape a string so that it can be used in a regular expression, so at that point, you might consider using a different approach such as Terry's

  • Related