¿No hay una map()función en la nueva versión HTML5-JavaScript? Recuerdo haber leído algo sobre ese tema ...
Martin Hennings
@ Martin: Buen punto, no maptanto como some. someayudaría, pero tendrías que pasarle una función.
TJ Crowder
Respuestas:
224
No hay nada incorporado que lo haga por usted, tendrá que escribir una función para ello.
Si sabe que las cadenas no contienen ninguno de los caracteres que son especiales en las expresiones regulares, puede hacer un poco de trampa, así:
if(newRegExp(substrings.join("|")).test(string)){// At least one match}
... que crea una expresión regular que es una serie de alternancias para las subcadenas que está buscando (por ejemplo, one|two) y pruebas para ver si hay coincidencias para alguna de ellas, pero si alguna de las subcadenas contiene caracteres especiales en expresiones regulares ( *, [, etc.), que lo tienes que escapar de ellos primero y que está mejor simplemente haciendo el bucle aburrida en su lugar.
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 +"'");}
Puede extenderse por encima de la solución mediante la eliminación de todos los caracteres de expresiones regulares, excepto el '|': new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
user007
El uso de indexOf puede ser demasiado confuso y producir un resultado extraño. Simplemente se puede poner para que coincida con la cadena utilizando el operador igual. por ejemplo, ('disconnect'.indexOf('connect') >= 0) === truepero('disconnect' === 'conenct') === false
kylewelsby
@halfcube: ¿Eh? No te entiendo, me temo. Nada en la respuesta anterior sugiere que 'disconnect' === 'connect'será todo menos eso false. Además, indexOfno es borroso, está muy claramente definido.
TJ Crowder
indexOfcoincidirá con ambos disconnecty connectdonde en un caso que he experimentado, estos son dos casos diferentes para los que quiero devolver resultados en condicional.
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}}
Chicos ... cuando era niño teníamos que usar estas cosas llamadas bucles 'for', y tenía que usar varias líneas y saber si su matriz estaba basada en 1 o cero, sí ... la mitad del tiempo que tenía se equivocó y tuvo que depurar y buscar un pequeño insecto llamado 'i'.
aamarks
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);
Además, devuelve la primera aparición de la palabra en la cadena, lo cual es muy útil. No solo un verdadero / falso.
Kai Noack
20
Para las personas que buscan en Google,
La respuesta sólida debería 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`}
o más corto: if (substrings.some (v => v === str)) {
kofifus
10
Tenga en cuenta que esta es una respuesta a una pregunta ligeramente diferente, que pregunta si una cadena contiene texto de una matriz de subcadenas. Este código verifica si una cadena es una de las subcadenas. Depende de lo que se entiende por "contiene", supongo.
fcrick
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]}}
editar: si el orden de las pruebas no importa, puede usar esto (con solo una variable de bucle):
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]}}
Su primer ejemplo no necesita la lenvariable, solo verifique i < arr.length.
GreySage
3
Si la matriz no es grande, puede simplemente hacer un bucle y verificar la cadena con cada subcadena individualmente indexOf(). Alternativamente, podría construir una expresión regular con subcadenas como alternativas, que pueden o no ser más eficientes.
Digamos que tenemos una lista de 100 subcadenas. ¿Qué forma sería más eficiente: RegExp o loop?
Diyorbek Sadullayev
3
Función Javascript para buscar una matriz de etiquetas o palabras clave utilizando una cadena de búsqueda o una matriz de cadenas de búsqueda. (Utiliza ES5 algún método de matriz y funciones de flecha 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;}
Ejemplo de uso:
var a =["a","b","c","d","e"];var b =["a","b"];if( contains(a, b)){// 1 or more matches found}
La mejor respuesta está aquí: esto también distingue entre mayúsculas y minúsculas
var specsFilter =[.....];var yourString ="......";//if found a matchif(specsFilter.some((element)=>{returnnewRegExp(element,"ig").test(yourString)})){// do something}
usando RegExp escapado para probar la aparición de "al menos una vez", de al menos una de las subcadenas.
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 ...'));
Si está trabajando con una larga lista de subcadenas que consisten en "palabras" completas separadas por espacios o cualquier otro carácter común, puede ser un poco inteligente en su búsqueda.
Primero divida su cadena en grupos de X, luego X + 1, luego X + 2, ..., hasta Y. X e Y deben ser el número de palabras en su subcadena con la menor cantidad de palabras, respectivamente. Por ejemplo, si X es 1 e Y es 4, "Alpha Beta Gamma Delta" se convierte en:
"Alfa" "Beta" "Gamma" "Delta"
"Alfa Beta" "Beta Gamma" "Delta Gamma"
"Alfa Beta Gamma" "Beta Gamma Delta"
"Alfa Beta Gamma Delta"
Si X sería 2 e Y sería 3, entonces omitirías la primera y la última fila.
Ahora puede buscar en esta lista rápidamente si la inserta en un Conjunto (o un Mapa), mucho más rápido que mediante la comparación de cadenas.
La desventaja es que no puede buscar subcadenas como "ta Gamm". Por supuesto, podría permitir eso dividiéndolo por carácter en lugar de por palabra, pero luego a menudo necesitaría construir un conjunto masivo y el tiempo / memoria dedicado a hacerlo supera los beneficios.
<!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()
función en la nueva versión HTML5-JavaScript? Recuerdo haber leído algo sobre ese tema ...map
tanto comosome
.some
ayudaría, pero tendrías que pasarle una función.Respuestas:
No hay nada incorporado que lo haga por usted, tendrá que escribir una función para ello.
Si sabe que las cadenas no contienen ninguno de los caracteres que son especiales en las expresiones regulares, puede hacer un poco de trampa, así:
... que crea una expresión regular que es una serie de alternancias para las subcadenas que está buscando (por ejemplo,
one|two
) y pruebas para ver si hay coincidencias para alguna de ellas, pero si alguna de las subcadenas contiene caracteres especiales en expresiones regulares (*
,[
, etc.), que lo tienes que escapar de ellos primero y que está mejor simplemente haciendo el bucle aburrida en su lugar.Ejemplo en vivo:
Mostrar fragmento de código
En un comentario sobre la pregunta, Martin pregunta sobre el nuevo
Array.prototype.map
método en ECMAScript5.map
no es de mucha ayuda, perosome
es:Ejemplo en vivo:
Mostrar fragmento de código
Solo lo tiene en implementaciones compatibles con ECMAScript5, aunque es trivial para polyfill.
Actualización en 2020 : el
some
ejemplo puede ser más simple con una función de flecha (ES2015 +), y puede usar enincludes
lugar deindexOf
:Ejemplo en vivo:
Mostrar fragmento de código
O incluso lanzarlo
bind
, aunque para mí la función de flecha es mucho más legible:Ejemplo en vivo:
Mostrar fragmento de código
fuente
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.('disconnect'.indexOf('connect') >= 0) === true
pero('disconnect' === 'conenct') === false
'disconnect' === 'connect'
será todo menos esofalse
. Además,indexOf
no es borroso, está muy claramente definido.indexOf
coincidirá con ambosdisconnect
yconnect
donde en un caso que he experimentado, estos son dos casos diferentes para los que quiero devolver resultados en condicional.fuente
Solución de una línea
Devuelve
true\false
si la subcadenaexists\does'nt exist
Necesita soporte para ES6
fuente
fuente
Para las personas que buscan en Google,
La respuesta sólida debería ser.
fuente
editar: si el orden de las pruebas no importa, puede usar esto (con solo una variable de bucle):
fuente
len
variable, solo verifiquei < arr.length
.Si la matriz no es grande, puede simplemente hacer un bucle y verificar la cadena con cada subcadena individualmente
indexOf()
. Alternativamente, podría construir una expresión regular con subcadenas como alternativas, que pueden o no ser más eficientes.fuente
Función Javascript para buscar una matriz de etiquetas o palabras clave utilizando una cadena de búsqueda o una matriz de cadenas de búsqueda. (Utiliza ES5 algún método de matriz y funciones de flecha ES6 )
Ejemplo de uso:
fuente
No es que te sugiera que vayas y extiendas / modifiques
String
el prototipo, pero esto es lo que he hecho:String.prototype.includes ()
fuente
A partir de la solución de TJ Crowder, creé un prototipo para tratar este problema:
fuente
Para soporte completo;)
fuente
La mejor respuesta está aquí: esto también distingue entre mayúsculas y minúsculas
fuente
Usando underscore.js o lodash.js, puede hacer lo siguiente en una matriz de cadenas:
Y en una sola cadena:
fuente
Esto es muy tarde, pero me encontré con este problema. En mi propio proyecto, utilicé lo siguiente para verificar si una cadena estaba en una matriz:
De esta manera, puede tomar una matriz predefinida y verificar si contiene una cadena:
fuente
aprovechando la respuesta de TJ Crowder
usando RegExp escapado para probar la aparición de "al menos una vez", de al menos una de las subcadenas.
fuente
Si está trabajando con una larga lista de subcadenas que consisten en "palabras" completas separadas por espacios o cualquier otro carácter común, puede ser un poco inteligente en su búsqueda.
Primero divida su cadena en grupos de X, luego X + 1, luego X + 2, ..., hasta Y. X e Y deben ser el número de palabras en su subcadena con la menor cantidad de palabras, respectivamente. Por ejemplo, si X es 1 e Y es 4, "Alpha Beta Gamma Delta" se convierte en:
"Alfa" "Beta" "Gamma" "Delta"
"Alfa Beta" "Beta Gamma" "Delta Gamma"
"Alfa Beta Gamma" "Beta Gamma Delta"
"Alfa Beta Gamma Delta"
Si X sería 2 e Y sería 3, entonces omitirías la primera y la última fila.
Ahora puede buscar en esta lista rápidamente si la inserta en un Conjunto (o un Mapa), mucho más rápido que mediante la comparación de cadenas.
La desventaja es que no puede buscar subcadenas como "ta Gamm". Por supuesto, podría permitir eso dividiéndolo por carácter en lugar de por palabra, pero luego a menudo necesitaría construir un conjunto masivo y el tiempo / memoria dedicado a hacerlo supera los beneficios.
fuente
Para soporte completo (adicionalmente a las versiones de @ricca ).
fuente
Puedes marcar así:
fuente
Usar filtro:
fuente