Não existe uma map()função na nova versão HTML5-JavaScript? Lembro-me de ter lido algo sobre o assunto ...
Martin Hennings
@ Martin: Bom ponto, nem maptanto some. someajudaria, mas você teria que passar uma função.
TJ Crowder
Respostas:
224
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(newRegExp(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.
var substrings =["one","two","three"];var str;// Setup
console.log("Substrings: "+ substrings.join(","));// Try it where we expect a match
str ="this has one";if(newRegExp(substrings.join("|")).test(str)){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}// Try it where we DON'T expect a match
str ="this doesn't have any";if(newRegExp(substrings.join("|")).test(str)){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}
var substrings =["one","two","three"];var str;// Setup
console.log("Substrings: "+ substrings.join(","));// Try it where we expect a match
str ="this has one";if(substrings.some(function(v){return str.indexOf(v)>=0;})){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}// Try it where we DON'T expect a match
str ="this doesn't have any";if(substrings.some(function(v){return str.indexOf(v)>=0;})){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}
const substrings =["one","two","three"];let str;// Setup
console.log("Substrings: "+ substrings.join(","));// Try it where we expect a match
str ="this has one";if(substrings.some(v => str.includes(v))){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}// Try it where we DON'T expect a match
str ="this doesn't have any";if(substrings.some(v => str.includes(v))){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}
const substrings =["one","two","three"];let str;// Setup
console.log("Substrings: "+ substrings.join(","));// Try it where we expect a match
str ="this has one";if(substrings.some(str.includes.bind(str))){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}// Try it where we DON'T expect a match
str ="this doesn't have any";if(substrings.some(str.includes.bind(str))){
console.log("Match using '"+ str +"'");}else{
console.log("No match using '"+ str +"'");}
Você pode estender acima solução, removendo todos os caracteres regex exceto o '|': new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
User007
o uso de indexOf pode ser muito confuso e gerar um resultado estranho. Ele pode ser simplesmente colocado para corresponder à string usando o operador igual. Por exemplo, ('disconnect'.indexOf('connect') >= 0) === truemas('disconnect' === 'conenct') === false
kylewels por
@halfcube: Hein? Não estou entendendo você, estou com medo. Nada na resposta acima sugere que 'disconnect' === 'connect'será tudo menos false. Além disso, indexOfnão é confuso, é muito claramente definido.
TJ Crowder
indexOfcorresponderá a ambos disconnecte connectonde, em um caso que eu experimentei, são dois casos diferentes para os quais eu quero retornar resultados condicionais
kylewelsby
54
var yourstring ='tasty food';// the string to check againstvar substrings =['foo','bar'],
length = substrings.length;while(length--){if(yourstring.indexOf(substrings[length])!=-1){// one of the substrings is in yourstring}}
Vocês, crianças ... quando eu era criança, tivemos que usar essas coisas chamadas 'for' loops, e você teve que usar várias linhas e saber se sua matriz era baseada em 1 ou zero, sim ... metade do tempo que você tinha errado e teve que depurar e procurar um pequeno bugger chamado 'i'.
precisa saber é
25
function containsAny(str, substrings){for(var i =0; i != substrings.length; i++){var substring = substrings[i];if(str.indexOf(substring)!=-1){return substring;}}returnnull;}var result = containsAny("defg",["ab","cd","ef"]);
console.log("String was found in substring "+ result);
Além disso, ele retorna a primeira ocorrência da palavra na string, o que é muito útil. Não é apenas um verdadeiro / falso.
Kai Noack
20
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`}
Observe que essa é uma resposta para uma pergunta um pouco diferente, que pergunta se uma string contém texto de uma matriz de substrings. Este código verifica se uma string é uma das substrings. Depende do que se entende por "contém", suponho.
fcrick 29/05
8
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]}}
Seu primeiro exemplo não precisa da lenvariável, basta verificar i < arr.length.
GreySage 26/02
3
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.
Digamos que temos uma lista de 100 substrings. Qual caminho seria mais eficiente: RegExp ou loop?
Diyorbek Sadullayev 27/06
3
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 stringsfunction contains(a, b){// array matchesif(Array.isArray(b)){return b.some(x => a.indexOf(x)>-1);}// string matchreturn 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}
A melhor resposta está aqui: Isso também não diferencia maiúsculas de minúsculas
var specsFilter =[.....];var yourString ="......";//if found a matchif(specsFilter.some((element)=>{returnnewRegExp(element,"ig").test(yourString)})){// do something}
usando RegExp com escape para testar a ocorrência "pelo menos uma vez", de pelo menos uma das substrings.
function buildSearch(substrings){returnnewRegExp(
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.
<!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>
map()
função na nova versão HTML5-JavaScript? Lembro-me de ter lido algo sobre o assunto ...map
tantosome
.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:
... 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:
Mostrar snippet de código
Em um comentário sobre a pergunta, Martin pergunta sobre o novo
Array.prototype.map
método no ECMAScript5.map
não é muita ajuda, massome
é:Exemplo ao vivo:
Mostrar snippet de código
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, emincludes
vez deindexOf
:Exemplo ao vivo:
Mostrar snippet de código
Ou até jogá
bind
-lo, embora para mim a função de seta seja muito mais legível:Exemplo ao vivo:
Mostrar snippet de código
fonte
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.('disconnect'.indexOf('connect') >= 0) === true
mas('disconnect' === 'conenct') === false
'disconnect' === 'connect'
será tudo menosfalse
. Além disso,indexOf
não é confuso, é muito claramente definido.indexOf
corresponderá a ambosdisconnect
econnect
onde, em um caso que eu experimentei, são dois casos diferentes para os quais eu quero retornar resultados condicionaisfonte
Solução de uma linha
Retorna
true\false
se substringexists\does'nt exist
Precisa de suporte do ES6
fonte
fonte
Para as pessoas pesquisando no Google,
A resposta sólida deve ser.
fonte
edit: Se a ordem dos testes não importa, você pode usá-lo (com apenas uma variável de loop):
fonte
len
variável, basta verificari < 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.fonte
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 )
Exemplo de uso:
fonte
Não que eu esteja sugerindo que você amplie / modifique
String
o protótipo, mas foi o que eu fiz:String.prototype.includes ()
fonte
Partindo da solução de TJ Crowder, criei um protótipo para lidar com esse problema:
fonte
Para suporte total;)
fonte
A melhor resposta está aqui: Isso também não diferencia maiúsculas de minúsculas
fonte
Usando underscore.js ou lodash.js, você pode fazer o seguinte em uma matriz de cadeias de caracteres:
E em uma única sequência:
fonte
É 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:
Dessa forma, você pode pegar uma matriz predefinida e verificar se ela contém uma sequência:
fonte
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.
fonte
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.
fonte
Para suporte completo (adicionalmente a @ricca 's verions ).
fonte
Você pode verificar assim:
fonte
Use filtro:
fonte