Bem direto. Em javascript, preciso verificar se uma string contém substrings mantidos em uma matriz.
map
tanto some
. some
ajudaria, mas você teria que passar uma função.
Bem direto. Em javascript, preciso verificar se uma string contém substrings mantidos em uma matriz.
map
tanto some
. some
ajudaria, mas você teria que passar uma função.
Respostas:
Não há nada embutido que faça isso por você, você terá que escrever uma função para ele.
Se você sabe que as strings não contêm nenhum caractere especial em expressões regulares, você pode trapacear um pouco, assim:
if (new RegExp(substrings.join("|")).test(string)) {
// At least one match
}
... que cria uma expressão regular que é uma série de alternâncias para as substrings que você está procurando (por exemplo, one|two
) e testa para verificar se há correspondências para alguma delas, mas se alguma das substrings contém caracteres especiais em regexes ( *
,[
etc.), você teria que escapar delas primeiro e é melhor fazer o ciclo chato.
Exemplo ao vivo:
Em um comentário sobre a pergunta, Martin pergunta sobre o novo Array.prototype.map
método no ECMAScript5. map
não é muita ajuda, mas some
é:
if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
// There's at least one
}
Exemplo ao vivo:
Você só o possui em implementações compatíveis com ECMAScript5, embora seja trivial o polyfill.
Atualização em 2020 : o some
exemplo pode ser mais simples com uma função de seta (ES2015 +) e você pode usar, em includes
vez de indexOf
:
if (substrings.some(v => str.includes(v))) {
// There's at least one
}
Exemplo ao vivo:
Ou até jogá bind
-lo, embora para mim a função de seta seja muito mais legível:
if (substrings.some(str.includes.bind(str))) {
// There's at least one
}
Exemplo ao vivo:
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.
('disconnect'.indexOf('connect') >= 0) === true
mas('disconnect' === 'conenct') === false
'disconnect' === 'connect'
será tudo menos false
. Além disso, indexOf
não é confuso, é muito claramente definido.
indexOf
corresponderá a ambos disconnect
e connect
onde, em um caso que eu experimentei, são dois casos diferentes para os quais eu quero retornar resultados condicionais
Solução de uma linha
substringsArray.some(substring=>yourBigString.includes(substring))
Retorna true\false
se substringexists\does'nt exist
Precisa de suporte do 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);
Para as pessoas pesquisando no Google,
A resposta sólida deve ser.
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: Se a ordem dos testes não importa, você pode usá-lo (com apenas uma variável de loop):
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
variável, basta verificar i < arr.length
.
Se a matriz não for grande, você pode simplesmente fazer um loop e verificar a string em cada substring individualmente usando indexOf()
. Como alternativa, você pode construir uma expressão regular com substrings como alternativas, que podem ou não ser mais eficientes.
Função Javascript para pesquisar uma matriz de tags ou palavras-chave usando uma string de pesquisa ou uma matriz de strings de pesquisa. (Usa ES5 algum método de matriz e funções de seta 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;
}
Exemplo de uso:
var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
// 1 or more matches found
}
Não que eu esteja sugerindo que você amplie / modifique String
o protótipo, mas foi o que eu fiz:
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
A melhor resposta está aqui: Isso também não diferencia maiúsculas de minúsculas
var specsFilter = [.....];
var yourString = "......";
//if found a match
if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
// do something
}
Usando underscore.js ou lodash.js, você pode fazer o seguinte em uma matriz de cadeias de caracteres:
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']
E em uma única sequência:
var contact = 'Billy';
var filters = ['Bill', 'Sarah'];
_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });
// true
É tarde demais, mas acabei de encontrar este problema. No meu próprio projeto, usei o seguinte para verificar se uma string estava em uma matriz:
["a","b"].includes('a') // true
["a","b"].includes('b') // true
["a","b"].includes('c') // false
Dessa forma, você pode pegar uma matriz predefinida e verificar se ela contém uma sequência:
var parameters = ['a','b']
parameters.includes('a') // true
com base na resposta de TJ Crowder
usando RegExp com escape para testar a ocorrência "pelo menos uma vez", de pelo menos uma das substrings.
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 ...'));
Se você estiver trabalhando com uma longa lista de substrings que consistem em "palavras" completas separadas por espaços ou qualquer outro caractere comum, você pode ser um pouco inteligente em sua pesquisa.
Primeiro divida sua string em grupos de X, depois X + 1, depois X + 2, ..., até Y. X e Y devem ser o número de palavras na sua substring com o menor número e a maior quantidade de palavras, respectivamente. Por exemplo, se X é 1 e Y é 4, "Alpha Beta Gamma Delta" se torna:
"Alfa" "Beta" "Gama" "Delta"
"Alpha Beta" "Beta Gamma" "Gamma Delta"
"Alpha Beta Gamma" "Beta Gamma Delta"
"Alpha Beta Gamma Delta"
Se X fosse 2 e Y fosse 3, você omitiria a primeira e a última linha.
Agora você pode pesquisar nessa lista rapidamente se inseri-la em um conjunto (ou mapa), muito mais rapidamente do que na comparação de cadeias.
A desvantagem é que você não pode procurar por substrings como "ta Gamm". É claro que você poderia permitir isso dividindo por caractere em vez de por palavra, mas muitas vezes precisaria criar um conjunto enorme e o tempo / memória gasto superando os benefícios.
Para suporte completo (adicionalmente a @ricca 's verions ).
wordsArray = ['hello', 'to', 'nice', 'day']
yourString = 'Hello. Today is a nice day'.toLowerCase()
result = wordsArray.every(w => yourString.includes(w))
console.log('result:', result)
Você pode verificar assim:
<!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';
Use filtro:
obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
map()
função na nova versão HTML5-JavaScript? Lembro-me de ter lido algo sobre o assunto ...