Unfortunately, JS is not great when it comes to internationalized case-insensitive string comparison. If you're just sticking to ASCII though, the solution is fairly straightforward (using filter
though, not where
):
function getMatches(query, arr) {
var lowerQuery = query.toLowerCase();
return _.filter(arr, function(term) {
return term.toLowerCase() == lowerQuery;
});
}
Or if you want to precompute everything because you expect to make a lot of queries in the same JS session:
var index = _.groupBy(arr, function(term) { return term.toLowerCase(); });
// Post-process index to reduce memory footprint by turning redundant values to nulls
// (which take up less memory than arrays with a string in them).
index = _.object(_.map(index, function(terms, key) {
return [key, (terms.length == 1 && terms[0].toLowerCase() == terms[0] ? null : terms)];
}));
function getMatches(query) {
var lowerQuery = query.toLowerCase();
return (lowerQuery in index ? index[lowerQuery] || lowerQuery : []);
}
This second method has the advantage of only computing toLowercase()
the minimal number of times and minimal data storage because of the post-processing step.
Here's a JSFiddle for both