Могу ли я использовать подстановочные знаки при поиске массива строк в Javascript?

Учитывая массив строк:

x = ["banana","apple","orange"]

Есть ли встроенный ярлык для выполнения поиска по шаблону?

т.е., возможно,

x.indexOf("*na*") //returns index of a string containing the substring na

Ответ 1

Развернувшись на ответ Pim, правильный способ сделать это (без jQuery) будет следующим:

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

Но действительно, если вы не используете эту функцию в нескольких местах, вы можете просто использовать существующий метод filter:

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

Версия RegExp аналогична, но я думаю, что она создаст немного больше служебных:

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

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

Он обеспечивает гибкость, позволяющую вам указать допустимую строку RegExp.

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

Ответ 2

Расширение ответа @Shmiddty, вот полезные идеи JavaScript:

  • Расширьте массив с помощью нового метода: Array.prototype.method = function(arg) { return result; }
  • Матрицы фильтров с использованием: Array.filter(function(e) { return true|false; })
  • Применить формулу к элементам в массиве: Array.map(function(e) { return formula(e); })
  • Используйте регулярные выражения: либо /.*na.*/, либо new Regex('.*na.*')
  • Используйте регулярные выражения для соответствия: var result = regex.test(input);
  • Используйте Array.prototype.reduce, чтобы агрегировать результат после запуска функции для каждого элемента массива

то есть. Я предпочитаю, чтобы входной аргумент был регулярным выражением, поэтому он дает вам:

  • Короткий, но универсальный вход, соответствующий шаблону,
    • например. содержит, начинается с, заканчивается ширина, а также более сложные соответствия
  • Возможность указать шаблон ввода в виде строки

РЕШЕНИЕ 1: фильтр, тест, карта и indexOf

Array.prototype.find = function(regex) {
  var arr = this;
  var matches = arr.filter( function(e) { return regex.test(e); } );
  return matches.map(function(e) { return arr.indexOf(e); } );
};
var 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: [0]
console.log(x.find(/e$/)); // Ends with 'e'? Outputs: [1,2]
console.log(x.find(/pear/)); // Contains 'pear'? Outputs: []

Ответ 3

Вы можете расширить прототип массива, чтобы найти совпадения в массиве

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

Затем вы можете вызвать find в своем массиве так

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

Ответ 4

Использование regex может сделать это в javascript

var searchin = item.toLowerCase();
var str = columnId;
str = str.replace(/[*]/g, ".*").toLowerCase().trim();
return new RegExp("^"+ str + "$").test(searchin);

Ответ 5

В дополнение ко всему, что было сказано, вы можете сделать это:

var x = ["banana", "apple", "orange"];
var y = [];
for (var i in x) {
    if (x[i].indexOf('na') == -1) {
        y.push(x[i]);
    }
}
x = y;

Вы не хотите .splice() массив, через который вы проходите цикл, так как это изменит длину массива и повлияет на цикл. Но вы можете выполнить цикл и создать второй массив только с теми значениями, которые хотите сохранить, а затем записать поверх исходного массива новый.

Это не лучше, чем другие ответы, это просто еще один способ сделать то же самое.