Can I use wildcards when searching an array of strings in Javascript?

You can extend the array prototype to find matches in an array

Array.prototype.find = function(match) {
    var matches = [];
    $.each(this, function(index, str) {
        if(str.indexOf(match) !== -1) {
            matches.push(index);
        }
    });
    return matches;
}

You can then call find on your array like so

// returns [0,3]
["banana","apple","orange", "testna"].find('na');

Expanding on Pim's answer, the correct way to do it (without jQuery) would be this:

Array.prototype.find = function(match) {
    return this.filter(function(item){
        return typeof item == 'string' && item.indexOf(match) > -1;
    });
}

But really, unless you're using this functionality in multiple places, you can just use the existing filter method:

var result = x.filter(function(item){
    return typeof item == 'string' && item.indexOf("na") > -1;            
});

The RegExp version is similar, but I think it will create a little bit more overhead:

Array.prototype.findReg = function(match) {
    var reg = new RegExp(match);

    return this.filter(function(item){
        return typeof item == 'string' && item.match(reg);
    });
}

It does provide the flexibility to allow you to specify a valid RegExp string, though.

x.findReg('a'); // returns all three
x.findReg("a$"); // returns only "banana" since it's looking for 'a' at the end of the string.

Extending on @Shmiddty's answer, here are useful JavaScript ideas:

  • Extend Array with a new method: Array.prototype.method = function(arg) { return result; }
  • Filter arrays using: Array.filter(function(e) { return true|false; })
  • Apply formula to elements in an array: Array.map(function(e) { return formula(e); })
  • Use regular expressions: either /.*na.*/ or new Regex('.*na.*')
  • Use regular expressions to match: let result = regex.test(input);
  • Use Array.prototype.reduce to aggergate a result after running a function on every element of an array

i.e. I prefer the input argument to be a regex, so, it gives you either:

  • A short but universal pattern matching input,
    • e.g. contains, starts with, ends width, as well as more sophisticated matches
  • The ability to specify an input pattern as a string

SOLUTION 1: filter, test, map and indexOf

Array.prototype.find = function(regex) {
  const arr = this;
  const matches = arr.filter( function(e) { return regex.test(e); } );
  return matches.map(function(e) { return arr.indexOf(e); } );
};
let x = [ "banana", "apple", "orange" ];
console.log(x.find(/na/)); // Contains 'na'? Outputs: [0]
console.log(x.find(/a/)); // Contains 'a'? Outputs: [0,1,2]
console.log(x.find(/^a/)); // Starts with 'a'? Outputs: [1]
console.log(x.find(/e$/)); // Ends with 'e'? Outputs: [1,2]
console.log(x.find(/pear/)); // Contains 'pear'? Outputs: []

SOLUTION 2: reduce, test

Array.prototype.find = function(regex) {
  return this.reduce(function (acc, curr, index, arr) {
    if (regex.test(curr)) { acc.push(index); }
    return acc;
  }, [ ]);
}
let x = [ "banana", "apple", "orange" ];
console.log(x.find(/na/)); // Contains 'na'? Outputs: [0]
console.log(x.find(/a/)); // Contains 'a'? Outputs: [0,1,2]
console.log(x.find(/^a/)); // Starts with 'a'? Outputs: [1]
console.log(x.find(/e$/)); // Ends with 'e'? Outputs: [1,2]
console.log(x.find(/pear/)); // Contains 'pear'? Outputs: []

Tags:

Javascript