Довольно прямо вперед. В javascript мне нужно проверить, содержит ли строка какие-либо подстроки в массиве.
map
так много, как some
. some
помогло бы, но вы должны были бы передать это функции.
Довольно прямо вперед. В javascript мне нужно проверить, содержит ли строка какие-либо подстроки в массиве.
map
так много, как some
. some
помогло бы, но вы должны были бы передать это функции.
Ответы:
Там нет ничего встроенного, что сделает это за вас, вам придется написать функцию для этого.
Если вы знаете, что строки не содержат символов, которые являются специальными в регулярных выражениях, то вы можете немного обмануть, например так:
if (new RegExp(substrings.join("|")).test(string)) {
// At least one match
}
... который создает регулярное выражение, представляющее собой серию чередований для подстрок, которые вы ищете (например, one|two
), и проверяет, есть ли совпадения для какой-либо из них, но если любая из подстрок содержит какие-либо специальные символы в регулярных выражениях ( *
, [
и т. д.) вы должны сначала избежать их, и вам лучше просто делать скучный цикл.
Живой пример:
В комментарии к этому вопросу Мартин спрашивает о новом Array.prototype.map
методе в ECMAScript5. map
не так уж много помочь, но some
это:
if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
// There's at least one
}
Живой пример:
У вас есть только в ECMAScript5-совместимых реализациях, хотя это тривиально для polyfill.
Обновление в 2020 году : some
пример может быть проще с функцией стрелки (ES2015 +), и вы можете использовать includes
вместо indexOf
:
if (substrings.some(v => str.includes(v))) {
// There's at least one
}
Живой пример:
Или даже бросить bind
на это, хотя для меня функция стрелки гораздо более читабельна:
if (substrings.some(str.includes.bind(str))) {
// There's at least one
}
Живой пример:
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.
('disconnect'.indexOf('connect') >= 0) === true
но('disconnect' === 'conenct') === false
'disconnect' === 'connect'
это будет что-либо кроме false
. Кроме того, indexOf
это не нечетко, это действительно очень четко определено.
indexOf
будет соответствовать обоим, disconnect
и connect
где в случае, в котором я находился, это два разных случая, для которых я хочу вернуть результаты в условном выражении.
Одноканальное решение
substringsArray.some(substring=>yourBigString.includes(substring))
Возвращает, true\false
если подстрокаexists\does'nt exist
Требуется поддержка ES6
function containsAny(str, substrings) {
for (var i = 0; i != substrings.length; i++) {
var substring = substrings[i];
if (str.indexOf(substring) != - 1) {
return substring;
}
}
return null;
}
var result = containsAny("defg", ["ab", "cd", "ef"]);
console.log("String was found in substring " + result);
Для людей, гуглящих,
Твердый ответ должен быть.
const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
// Will only return when the `str` is included in the `substrings`
}
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = 0, len = arr.length; i < len; ++i) {
if (str.indexOf(arr[i]) != -1) {
// str contains arr[i]
}
}
edit: если порядок тестов не имеет значения, вы можете использовать это (только с одной переменной цикла):
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = arr.length - 1; i >= 0; --i) {
if (str.indexOf(arr[i]) != -1) {
// str contains arr[i]
}
}
len
переменной, просто проверьте i < arr.length
.
Если массив не большой, вы можете просто зациклить и проверить строку для каждой подстроки в отдельности, используя indexOf()
. В качестве альтернативы вы можете создать регулярное выражение с подстрокой в качестве альтернативы, что может быть или не быть более эффективным.
Функция Javascript для поиска в массиве тегов или ключевых слов, используя строку поиска или массив строк поиска. (Использует ES5 некоторый метод массива и функции стрелок ES6 )
// returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
function contains(a, b) {
// array matches
if (Array.isArray(b)) {
return b.some(x => a.indexOf(x) > -1);
}
// string match
return a.indexOf(b) > -1;
}
Пример использования:
var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
// 1 or more matches found
}
Не то чтобы я предлагал вам пойти и расширить / модифицировать String
прототип, но это то, что я сделал:
String.prototype.includes = function (includes) {
console.warn("String.prototype.includes() has been modified.");
return function (searchString, position) {
if (searchString instanceof Array) {
for (var i = 0; i < searchString.length; i++) {
if (includes.call(this, searchString[i], position)) {
return true;
}
}
return false;
} else {
return includes.call(this, searchString, position);
}
}
}(String.prototype.includes);
console.log('"Hello, World!".includes("foo");', "Hello, World!".includes("foo") ); // false
console.log('"Hello, World!".includes(",");', "Hello, World!".includes(",") ); // true
console.log('"Hello, World!".includes(["foo", ","])', "Hello, World!".includes(["foo", ","]) ); // true
console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false
Лучший ответ здесь: это также без учета регистра
var specsFilter = [.....];
var yourString = "......";
//if found a match
if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
// do something
}
Используя underscore.js или lodash.js, вы можете сделать следующее для массива строк:
var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];
var filters = ['Bill', 'Sarah'];
contacts = _.filter(contacts, function(contact) {
return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
});
// ['John']
И на одной строке:
var contact = 'Billy';
var filters = ['Bill', 'Sarah'];
_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });
// true
Это супер поздно, но я только столкнулся с этой проблемой. В моем собственном проекте я использовал следующее, чтобы проверить, была ли строка в массиве:
["a","b"].includes('a') // true
["a","b"].includes('b') // true
["a","b"].includes('c') // false
Таким образом, вы можете взять предопределенный массив и проверить, содержит ли он строку:
var parameters = ['a','b']
parameters.includes('a') // true
опираясь на ответ TJ Crowder
использование экранированного RegExp для проверки на наличие «хотя бы одного» хотя бы одной из подстрок.
function buildSearch(substrings) {
return new RegExp(
substrings
.map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
.join('{1,}|') + '{1,}'
);
}
var pattern = buildSearch(['hello','world']);
console.log(pattern.test('hello there'));
console.log(pattern.test('what a wonderful world'));
console.log(pattern.test('my name is ...'));
Если вы работаете с длинным списком подстрок, состоящих из полных «слов», разделенных пробелами, или любого другого общего символа, вы можете быть немного хитрыми в своем поиске.
Сначала разделите вашу строку на группы по X, затем X + 1, затем X + 2, ..., до Y. X и Y должны быть числом слов в вашей подстроке с наименьшим и большинством слов соответственно. Например, если X равен 1, а Y равен 4, «Альфа-бета-гамма-дельта» становится:
"Альфа" "Бета" "Гамма" "Дельта"
"Альфа Бета" "Бета Гамма" "Гамма Дельта"
"Альфа Бета Гамма" "Бета Гамма Дельта"
"Альфа Бета Гамма Дельта"
Если X будет 2 и Y будет 3, то вы пропустите первый и последний ряд.
Теперь вы можете быстро выполнить поиск в этом списке, если вставите его в набор (или карту), намного быстрее, чем при сравнении строк.
Недостатком является то, что вы не можете искать подстроки, такие как "Ta Gamm". Конечно, вы можете учесть это, разделяя по символам, а не по словам, но тогда вам часто придется создавать массивный сет, и затраченное на это время / память перевешивает преимущества.
Для полной поддержки (дополнительно к версиям @ricca ).
wordsArray = ['hello', 'to', 'nice', 'day']
yourString = 'Hello. Today is a nice day'.toLowerCase()
result = wordsArray.every(w => yourString.includes(w))
console.log('result:', result)
Вы можете проверить так:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var list = ["bad", "words", "include"]
var sentence = $("#comments_text").val()
$.each(list, function( index, value ) {
if (sentence.indexOf(value) > -1) {
console.log(value)
}
});
});
</script>
</head>
<body>
<input id="comments_text" value="This is a bad, with include test">
</body>
</html>
let obj = [{name : 'amit'},{name : 'arti'},{name : 'sumit'}];
let input = 'it';
Использовать фильтр:
obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
map()
функции в новой HTML5-JavaScript-версии? Я помню, что читал что-то на эту тему ...