N'y a-t-il pas une map()fonction dans la nouvelle version HTML5-JavaScript? Je me souviens avoir lu quelque chose sur ce sujet ...
Martin Hennings
@Martin: Bon point, pas maptant que ça some. someaiderait, mais il faudrait lui passer une fonction.
TJ Crowder
Réponses:
224
Il n'y a rien de intégré qui fera cela pour vous, vous devrez écrire une fonction pour cela.
Si vous savez que les chaînes ne contiennent aucun des caractères spéciaux dans les expressions régulières, vous pouvez tricher un peu, comme ceci:
if(newRegExp(substrings.join("|")).test(string)){// At least one match}
... qui crée une expression régulière qui est une série d' alternatives pour les sous-chaînes que vous recherchez (par exemple, one|two) et teste pour voir s'il y a des correspondances pour l'une d'entre elles, mais si l'une des sous-chaînes contient des caractères spéciaux dans les expressions rationnelles ( *,[ , etc.), vous auriez à les échapper et vous êtes mieux faire juste la boucle ennuyeuse à la place.
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 +"'");}
Dans un commentaire sur la question, Martin pose des questions sur la nouvelle Array.prototype.mapméthode dans ECMAScript5. mapn'est pas très utile, mais someest:
if(substrings.some(function(v){return str.indexOf(v)>=0;})){// There's at least one}
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 +"'");}
Vous pouvez étendre au- dessus solution en supprimant tous les caractères regex sauf le « | »: new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
user007
l'utilisation d'indexOf peut être trop floue et donner un résultat étrange. Il peut être simplement mis pour correspondre à la chaîne en utilisant l'opérateur égal. eg ('disconnect'.indexOf('connect') >= 0) === truebut('disconnect' === 'conenct') === false
kylewelspar
@halfcube: Hein? Je ne te comprends pas, j'en ai peur. Rien dans la réponse ci-dessus ne suggère que ce 'disconnect' === 'connect'sera autre chose false. De plus, ce indexOfn'est pas flou, c'est vraiment très clairement défini.
TJ Crowder
indexOfcorrespondra aux deux disconnectet connectoù, dans un cas que j'ai vécu, ce sont deux cas différents pour lesquels je veux renvoyer des résultats dans un conditionnel.
kylewelspar
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}}
Excellente solution utilisant les fonctions fléchées
GuerillaRadio
7
Vous les enfants ... à l'époque où j'étais enfant, nous devions utiliser ces choses appelées boucles `` for '', et vous deviez utiliser plusieurs lignes et savoir si votre tableau était basé sur 1 ou zéro, oui ... la moitié du temps il a mal et a dû déboguer et rechercher un petit bugger appelé «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);
De plus, il renvoie la première occurrence du mot dans la chaîne, ce qui est très utile. Pas seulement un vrai / faux.
Kai Noack
20
Pour les gens qui recherchent sur Google,
La réponse solide devrait être.
const substrings =['connect','ready'];const str ='disconnect';if(substrings.some(v => str === v)){// Will only return when the `str` is included in the `substrings`}
ou plus court: if (substrings.some (v => v === str)) {
kofifus
10
Notez qu'il s'agit d'une réponse à une question légèrement différente, qui demande si une chaîne contient du texte d'un tableau de sous-chaînes. Ce code vérifie si une chaîne est l' une des sous-chaînes. Cela dépend de ce que l'on entend par «contient», je suppose.
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]}}
edit: Si l'ordre des tests n'a pas d'importance, vous pouvez utiliser ceci (avec une seule variable de boucle):
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]}}
Votre premier exemple n'a pas besoin de la lenvariable, vérifiez simplement i < arr.length.
GreySage le
3
Si le tableau n'est pas volumineux, vous pouvez simplement effectuer une boucle et vérifier la chaîne par rapport à chaque sous-chaîne individuellement en utilisant indexOf(). Vous pouvez également construire une expression régulière avec des sous-chaînes comme alternatives, ce qui peut être plus efficace ou non.
Disons que nous avons une liste de 100 sous-chaînes. Quel moyen serait le plus efficace: RegExp ou boucle?
Diyorbek Sadullayev le
3
Fonction Javascript pour rechercher un tableau de balises ou de mots-clés à l'aide d'une chaîne de recherche ou d'un tableau de chaînes de recherche. (Utilise une méthode de tableau ES5 et des fonctions fléchées 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;}
Exemple d'utilisation:
var a =["a","b","c","d","e"];var b =["a","b"];if( contains(a, b)){// 1 or more matches found}
La meilleure réponse est ici: Ceci est également insensible à la casse
var specsFilter =[.....];var yourString ="......";//if found a matchif(specsFilter.some((element)=>{returnnewRegExp(element,"ig").test(yourString)})){// do something}
C'est super tard, mais je viens de rencontrer ce problème. Dans mon propre projet, j'ai utilisé ce qui suit pour vérifier si une chaîne était dans un tableau:
en utilisant RegExp échappé pour tester l'occurrence "au moins une fois" d'au moins une des sous-chaînes.
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 vous travaillez avec une longue liste de sous-chaînes composées de "mots" complets séparés par des espaces ou tout autre caractère courant, vous pouvez être un peu intelligent dans votre recherche.
Commencez par diviser votre chaîne en groupes de X, puis X + 1, puis X + 2, ..., jusqu'à Y. X et Y devraient être le nombre de mots de votre sous-chaîne avec respectivement le moins et le plus grand nombre de mots. Par exemple, si X est 1 et Y est 4, "Alpha Beta Gamma Delta" devient:
"Alpha" "Bêta" "Gamma" "Delta"
"Alpha Beta" "Beta Gamma" "Gamma Delta"
"Alpha Beta Gamma" "Beta Gamma Delta"
"Alpha Beta Gamma Delta"
Si X est 2 et Y 3, alors vous omettez la première et la dernière ligne.
Vous pouvez désormais rechercher rapidement dans cette liste si vous l'insérez dans un Set (ou une Map), bien plus rapidement que par comparaison de chaînes.
L'inconvénient est que vous ne pouvez pas rechercher des sous-chaînes comme "ta Gamm". Bien sûr, vous pouvez permettre cela en divisant par caractère plutôt que par mot, mais vous auriez souvent besoin de créer un ensemble massif et le temps / mémoire passé à le faire l'emporte sur les avantages.
<!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()
fonction dans la nouvelle version HTML5-JavaScript? Je me souviens avoir lu quelque chose sur ce sujet ...map
tant que çasome
.some
aiderait, mais il faudrait lui passer une fonction.Réponses:
Il n'y a rien de intégré qui fera cela pour vous, vous devrez écrire une fonction pour cela.
Si vous savez que les chaînes ne contiennent aucun des caractères spéciaux dans les expressions régulières, vous pouvez tricher un peu, comme ceci:
... qui crée une expression régulière qui est une série d' alternatives pour les sous-chaînes que vous recherchez (par exemple,
one|two
) et teste pour voir s'il y a des correspondances pour l'une d'entre elles, mais si l'une des sous-chaînes contient des caractères spéciaux dans les expressions rationnelles (*
,[
, etc.), vous auriez à les échapper et vous êtes mieux faire juste la boucle ennuyeuse à la place.Exemple en direct:
Afficher l'extrait de code
Dans un commentaire sur la question, Martin pose des questions sur la nouvelle
Array.prototype.map
méthode dans ECMAScript5.map
n'est pas très utile, maissome
est:Exemple en direct:
Afficher l'extrait de code
Vous ne l'avez que sur les implémentations compatibles ECMAScript5, bien qu'il soit trivial de polyfill.
Mise à jour en 2020 : l'
some
exemple peut être plus simple avec une fonction de flèche (ES2015 +), et vous pouvez utiliserincludes
plutôt queindexOf
:Exemple en direct:
Afficher l'extrait de code
Ou même lancez-
bind
vous, même si pour moi la fonction de flèche est beaucoup plus lisible:Exemple en direct:
Afficher l'extrait de code
la source
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.('disconnect'.indexOf('connect') >= 0) === true
but('disconnect' === 'conenct') === false
'disconnect' === 'connect'
sera autre chosefalse
. De plus, ceindexOf
n'est pas flou, c'est vraiment très clairement défini.indexOf
correspondra aux deuxdisconnect
etconnect
où, dans un cas que j'ai vécu, ce sont deux cas différents pour lesquels je veux renvoyer des résultats dans un conditionnel.la source
Solution une ligne
Renvoie
true\false
si sous-chaîneexists\does'nt exist
Nécessite le support ES6
la source
la source
Pour les gens qui recherchent sur Google,
La réponse solide devrait être.
la source
edit: Si l'ordre des tests n'a pas d'importance, vous pouvez utiliser ceci (avec une seule variable de boucle):
la source
len
variable, vérifiez simplementi < arr.length
.Si le tableau n'est pas volumineux, vous pouvez simplement effectuer une boucle et vérifier la chaîne par rapport à chaque sous-chaîne individuellement en utilisant
indexOf()
. Vous pouvez également construire une expression régulière avec des sous-chaînes comme alternatives, ce qui peut être plus efficace ou non.la source
Fonction Javascript pour rechercher un tableau de balises ou de mots-clés à l'aide d'une chaîne de recherche ou d'un tableau de chaînes de recherche. (Utilise une méthode de tableau ES5 et des fonctions fléchées ES6 )
Exemple d'utilisation:
la source
Non pas que je suggère que vous alliez étendre / modifier
String
le prototype de, mais c'est ce que j'ai fait:String.prototype.includes ()
la source
En m'inspirant de la solution de TJ Crowder, j'ai créé un prototype pour résoudre ce problème:
la source
Pour un support complet;)
la source
La meilleure réponse est ici: Ceci est également insensible à la casse
la source
En utilisant underscore.js ou lodash.js, vous pouvez effectuer les opérations suivantes sur un tableau de chaînes:
Et sur une seule chaîne:
la source
C'est super tard, mais je viens de rencontrer ce problème. Dans mon propre projet, j'ai utilisé ce qui suit pour vérifier si une chaîne était dans un tableau:
De cette façon, vous pouvez prendre un tableau prédéfini et vérifier s'il contient une chaîne:
la source
s'appuyant sur la réponse de TJ Crowder
en utilisant RegExp échappé pour tester l'occurrence "au moins une fois" d'au moins une des sous-chaînes.
la source
Si vous travaillez avec une longue liste de sous-chaînes composées de "mots" complets séparés par des espaces ou tout autre caractère courant, vous pouvez être un peu intelligent dans votre recherche.
Commencez par diviser votre chaîne en groupes de X, puis X + 1, puis X + 2, ..., jusqu'à Y. X et Y devraient être le nombre de mots de votre sous-chaîne avec respectivement le moins et le plus grand nombre de mots. Par exemple, si X est 1 et Y est 4, "Alpha Beta Gamma Delta" devient:
"Alpha" "Bêta" "Gamma" "Delta"
"Alpha Beta" "Beta Gamma" "Gamma Delta"
"Alpha Beta Gamma" "Beta Gamma Delta"
"Alpha Beta Gamma Delta"
Si X est 2 et Y 3, alors vous omettez la première et la dernière ligne.
Vous pouvez désormais rechercher rapidement dans cette liste si vous l'insérez dans un Set (ou une Map), bien plus rapidement que par comparaison de chaînes.
L'inconvénient est que vous ne pouvez pas rechercher des sous-chaînes comme "ta Gamm". Bien sûr, vous pouvez permettre cela en divisant par caractère plutôt que par mot, mais vous auriez souvent besoin de créer un ensemble massif et le temps / mémoire passé à le faire l'emporte sur les avantages.
la source
Pour un support complet (en plus des versions de @ricca ).
la source
Vous pouvez vérifier comme ceci:
la source
Utilisez le filtre:
la source