136

I have an array of strings that I need to loop and check against with another passed in string.

var filterstrings = ['firststring','secondstring','thridstring'];
var passedinstring = localStorage.getItem("passedinstring");

for (i = 0; i < filterstrings.lines.length; i++) {
    if (passedinstring.includes(filterstrings[i])) {
        alert("string detected");
    }
}

How do I ensure that case sensitivity is ignored here (preferably by using regex) when filtering, if the var passedinstring were to have strings like FirsTsTriNg or fiRSTStrING?

dthree
  • 18,488
  • 11
  • 69
  • 103
LegendDemonSlayer
  • 1,459
  • 2
  • 8
  • 13
  • Use a common case or create a regex and use something like `.some` along with it – Rajesh Jan 08 '18 at 06:44
  • 7
    This shouldn't be marked as a duplicate. The advantage of using `includes` over regex is that it covers scenarios where your string contains regex special characters. – Joao Jul 07 '18 at 19:54

10 Answers10

92

You can create a RegExp from filterstrings first

var filterstrings = ['firststring','secondstring','thridstring'];
var regex = new RegExp( filterstrings.join( "|" ), "i");

then test if the passedinstring is there

var isAvailable = regex.test( passedinstring ); 
user229044
  • 222,134
  • 40
  • 319
  • 330
gurvinder372
  • 64,240
  • 8
  • 67
  • 88
  • 5
    Note that firststringtest will also return true here. with ES5, `filterstrings.map((a) => { return a.toLowerCase() }).includes(passedinstring.toLowerCase())` may be a solution for this problem. – Jacob Morris Nov 08 '19 at 14:41
  • 5
    `filterstrings` must be escaped, otherwise you risk ending up with a broken regex, or one with unexpected behavior. – Matteo Italia Nov 24 '20 at 11:33
  • How much slower is this comparing to .includes() ? – trainoasis Feb 10 '21 at 12:45
  • 2
    This shouldn't be an acceptable answer! Whoever seeks for an answer and stumbled upon this answer - BEWARE! this will return `true` for any sub sequence can be found in the array. ```[1,2,3].includes(12) // false new RegExp([1,2,3].join("|"), "i").test(12) // true!!! ["Hello","World"].includes("HelloWorld") // false \n new RegExp(["Hello", "World"].join("|"), "i").test("HelloWorld") // true!!!``` – Tzahi Leh Aug 18 '21 at 13:32
  • 1
    Mapping random strings to regex patterns is not a good idea, unless you really know that those strings won't include special characters. – Robo Robok Nov 20 '21 at 21:44
62

You can simply convert the passedinstring to lowercase.

var passedinstring = localStorage.getItem("passedinstring").toLowerCase();
Nabin Paudyal
  • 1,533
  • 7
  • 14
  • 6
    well, it works in the given case but I guess we want it to work the other way around as well... (i.e the filtered strings also having capital letters) – romainm Mar 29 '19 at 09:21
  • 5
    If you want the other way to work as well, just use toLowerCase() on the inputted string as well. – Lengo Jul 16 '21 at 14:32
55

ES6 array method filter() can simplify the solution to a single line. Use includes() method to determine whether an array includes a certain value among its entries in conjunction to the toLowerCase() method to convert it to lowercase.

var filterstrings = ['firststring','secondstring','thridstring'];
var passedinstring = localStorage.getItem("passedinstring");

// convert each string from filterstrings and passedinstring to lowercase
// to avoid case sensitive issue.
filteredStrings = filterstrings.filter((str) => str.toLowerCase().includes(passedinstring.toLowerCase())
cngzz1
  • 135
  • 2
  • 9
Kamran Khatti
  • 3,083
  • 1
  • 17
  • 27
  • 2
    this is a great answer! This is a very simple single-line solution. I'm using the `filteredStrings` line within a filter, and I just check if the length > 0 in the encapsulating filter statement – Jan Jul 22 '20 at 21:31
  • 2
    Thanks - its always appreciated when people answer old questions with the latest functionality! – codingbryan Nov 07 '20 at 22:05
  • 1
    Using [localeCompare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) would be safer. There can be problems with plain `.toLowerCase()` - please see Jon Skeet's presentation on YouTube [Back to basics: the mess we've made of our fundamental data types](https://youtu.be/l3nPJ-yK-LU?t=1266) for more information. – Andrew Morton Jun 17 '21 at 16:45
  • 2
    I've used a variation on this: filteredstrings = filterstrings.some(e => e.toUpperCase().includes(activeSearch.toUpperCase())) – CosetteN Oct 01 '21 at 17:40
14

convert filterstring and passedinstring to lowercase and compare

var filterstrings = ['firststring','secondstring','thridstring'];
var passedinstring = 
localStorage.getItem("passedinstring").toLowerCase();

for (i = 0; i < filterstrings.lines.length; i++) {
   if (passedinstring.includes(filterstrings[i].toLowerCase())) {
       alert("string detected");
   }
}
Saurabh Mistry
  • 11,077
  • 4
  • 41
  • 64
13

You can switch .includes with the .some method which returns a boolean.
It will exit as soon as a match was found, which is great for performance for huge arrays:

.some(item => item.toLowerCase() == lookup.toLowerCase())

Demo:

var arr = ['foo','bar','bar'];
var lookup = "bAr";

// case-sensetive
console.log( arr.includes(lookup) )

// case-insensetive without caring about the type
console.log( arr.some(x => x.toLowerCase() == lookup.toLowerCase()) ) 

Or define your own Array prototype method with a unique name:

// the name ("_includes") should be unique enough not to ever be overriten 
// by future language updates or 3rd-party scripts
Array.prototype._includes = function(target){ 
  return this.some(x => x.toLowerCase() == (target||'').toLowerCase()) 
}

console.log( 
  ['foo', 'bar', 'bar']._includes("bAr") 
)
vsync
  • 103,437
  • 51
  • 275
  • 359
  • It could be even better performance-wise, if you do `lookup.toLowerCase()` outside of the loop. – Tomas Loksa Mar 25 '22 at 09:40
  • @TomášLokša - I tend to provide the simplest solution and it is up to the copy-paster to adopt it to their needs. Many answers here can be easily improved by it might not fit everyone or make the solution less easy to understand at a quick glass, which I want to avoid at some situations as this one – vsync Mar 25 '22 at 14:50
  • Ah, got it :) Anyway, thanks for your solution, it was really useful to me. – Tomas Loksa Mar 26 '22 at 18:10
10

Fixed case sensitivity issue using toLowerCase(). It turns all the string to lower case while comparing.

var product=productList.filter((x) => x.Name.toLowerCase().includes(("Active").toLowerCase()))
R15
  • 10,727
  • 13
  • 68
  • 139
4

My option is comparing UPPER with UPPER or lower with lower transforming both sides (i did it often in SQL):

    var filterstrings = ['firststring','secondstring','thirDstrIng'];
    var passedinstring =  'ThIrDsTrInG3';
    
    //used for of just to make it more readable
    for (filterstring of filterstrings) {
        if (passedinstring.toUpperCase().includes(filterstring.toUpperCase())) {
            alert("string detected");
        }
    
    }

Prompts string detected

DDS
  • 2,048
  • 13
  • 28
4
var filterstrings = ['firststring','secondstring','thridstring'];
var passedinstring = localStorage.getItem("passedinstring");

filterstrings.filter(item => item.name.toLowerCase().includes(passedinstring.toLowerCase()))
  • 2
    Your solution is very similar to this one: https://stackoverflow.com/a/63030383/3216427 just replacing `(str) => str.toLowerCase()...` by `item => item.name.toLowerCase()...`. Can you explain what this difference changes and why you think this is an improved solution? – joanis Nov 26 '21 at 14:32
3

I believe this would be simpler, shorter and more understandable.

  const q = new RegExp(query, 'i');

  filteredUsers = users.filter((user: User) => {
    return (
      user.entity.short.match(q) ||
      user.firstname.match(q) ||
      user.lastname.match(q)
    );
  });
Mianala Loharano
  • 281
  • 2
  • 12
  • This seems to be filtering a different set of data … and assumes that `query` won't include any characters with special meaning in regular expressions. – Quentin May 18 '21 at 16:22
-1

You can try this.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
string = fruits.join(' ').toUpperCase();
// Output"BANANA ORANGE APPLE MANGO"
Shantesh Sindgi
  • 235
  • 3
  • 4