Czy nie ma map()funkcji w nowej wersji HTML5-JavaScript? Pamiętam, że czytałem coś na ten temat ...
Martin Hennings,
@Martin: Słuszna uwaga, nie maptyle some. somepomogłoby, ale musiałbyś przekazać mu funkcję.
TJ Crowder
Odpowiedzi:
222
Nie ma nic wbudowanego, co zrobi to za Ciebie, będziesz musiał napisać dla niego funkcję.
Jeśli wiesz, że ciągi znaków nie zawierają żadnych znaków specjalnych w wyrażeniach regularnych, możesz trochę oszukać, na przykład:
if(newRegExp(substrings.join("|")).test(string)){// At least one match}
... które tworzy wyrażenie regularne, które jest serią naprzemiennych podciągów, których szukasz (np. one|two) i sprawdza, czy są dopasowania dla któregokolwiek z nich, ale czy którykolwiek z podciągów zawiera znaki, które są specjalne (w regexes *, [itp), trzeba je najpierw do ucieczki, a ty lepiej po prostu robi pętlę zamiast nudnego.
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 +"'");}
Można przedłużyć powyżej rozwiązania, usuwając wszystkie znaki regex wyjątkiem „|”: new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
user007
użycie indexOf może być zbyt rozmyte i dać dziwny wynik. Można go po prostu dopasować do ciągu za pomocą operatora równości. np. ('disconnect'.indexOf('connect') >= 0) === trueale('disconnect' === 'conenct') === false
kylewelsby
@halfcube: Hę? Nie rozumiem cię, obawiam się. Nic w powyższej odpowiedzi nie sugeruje, że 'disconnect' === 'connect'będzie to wszystko inne false. Nie indexOfjest też rozmyty, jest rzeczywiście bardzo jasno zdefiniowany.
TJ Crowder
indexOfdopasuje oba disconnecti connectgdzie w przypadku, którego doświadczyłem, są to dwa różne przypadki, dla których chcę zwrócić wyniki w postaci warunkowej.
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}}
Świetne rozwiązanie wykorzystujące funkcje strzałkowe
GuerillaRadio
7
Wy dzieciaki ... kiedy byłem dzieckiem, musieliśmy używać tych rzeczy zwanych pętlami `` for '' i musieliście używać wielu linii i wiedzieć, czy wasza tablica opierała się na 1 czy zero, tak ... o połowę krócej było źle i musiałem debugować i uważać na mały błąd o nazwie „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);
Dodatkowo zwraca pierwsze wystąpienie słowa w ciągu, co jest bardzo pomocne. Nie tylko prawda / fałsz.
Kai Noack
20
Dla osób szukających w Google,
Solidna odpowiedź powinna brzmieć.
const substrings =['connect','ready'];const str ='disconnect';if(substrings.some(v => str === v)){// Will only return when the `str` is included in the `substrings`}
lub krócej: if (substrings.some (v => v === str)) {
kofifus
10
Zauważ, że jest to odpowiedź na nieco inne pytanie, które dotyczy pytania, czy ciąg zawiera tekst z tablicy podciągów. Ten kod sprawdza, czy ciąg jest jednym z podciągów. Przypuszczam, że zależy od tego, co rozumie się przez „zawiera”.
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]}}
edycja: Jeśli kolejność testów nie ma znaczenia, możesz użyć tego (tylko z jedną zmienną pętli):
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]}}
Twój pierwszy przykład nie potrzebuje lenzmiennej, po prostu sprawdź i < arr.length.
GreySage
3
Jeśli tablica nie jest duża, możesz po prostu zapętlić i sprawdzić ciąg z każdym podciągiem indywidualnie, używając indexOf(). Alternatywnie możesz skonstruować wyrażenie regularne z podciągami jako alternatywami, które mogą być bardziej wydajne lub nie.
Powiedzmy, że mamy listę 100 podciągów. Który sposób byłby bardziej wydajny: RegExp czy pętla?
Diyorbek Sadullayev
3
Funkcja JavaScript do przeszukiwania tablicy tagów lub słów kluczowych za pomocą ciągu wyszukiwania lub tablicy ciągów wyszukiwania. (Używa ES5 jakiś sposób tablicy i ES6 strzałka funkcje )
// 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;}
Przykładowe użycie:
var a =["a","b","c","d","e"];var b =["a","b"];if( contains(a, b)){// 1 or more matches found}
Najlepsza odpowiedź brzmi: tutaj również nie jest rozróżniana wielkość liter
var specsFilter =[.....];var yourString ="......";//if found a matchif(specsFilter.some((element)=>{returnnewRegExp(element,"ig").test(yourString)})){// do something}
używanie wyrażenia Escaped RegExp do testowania wystąpienia „co najmniej raz” co najmniej jednego z podciągów.
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 ...'));
Jeśli pracujesz z długą listą podciągów składającą się z pełnych „słów” oddzielonych spacjami lub innymi popularnymi znakami, możesz być trochę sprytny w wyszukiwaniu.
Najpierw podziel ciąg na grupy X, potem X + 1, potem X + 2, ..., aż do Y. X i Y powinny być liczbą słów w podłańcuchu zawierającą odpowiednio najmniej i najwięcej słów. Na przykład jeśli X wynosi 1, a Y wynosi 4, „Alpha Beta Gamma Delta” zmienia się na:
„Alfa” „Beta” „Gamma” „Delta”
„Alpha Beta” „Beta Gamma” „Gamma Delta”
„Alpha Beta Gamma” „Beta Gamma Delta”
„Alpha Beta Gamma Delta”
Jeśli X będzie równe 2, a Y będzie 3, pominiesz pierwszy i ostatni wiersz.
Teraz możesz szybko przeszukiwać tę listę, jeśli wstawisz ją do zestawu (lub mapy), znacznie szybciej niż przez porównanie ciągów.
Wadą jest to, że nie możesz wyszukiwać podciągów, takich jak „ta Gamm”. Oczywiście możesz na to pozwolić, dzieląc się według znaków zamiast słów, ale wtedy często musiałbyś zbudować ogromny zestaw, a czas / pamięć spędzona na tym przeważają nad korzyściami.
<!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()
funkcji w nowej wersji HTML5-JavaScript? Pamiętam, że czytałem coś na ten temat ...map
tylesome
.some
pomogłoby, ale musiałbyś przekazać mu funkcję.Odpowiedzi:
Nie ma nic wbudowanego, co zrobi to za Ciebie, będziesz musiał napisać dla niego funkcję.
Jeśli wiesz, że ciągi znaków nie zawierają żadnych znaków specjalnych w wyrażeniach regularnych, możesz trochę oszukać, na przykład:
... które tworzy wyrażenie regularne, które jest serią naprzemiennych podciągów, których szukasz (np.
one|two
) i sprawdza, czy są dopasowania dla któregokolwiek z nich, ale czy którykolwiek z podciągów zawiera znaki, które są specjalne (w regexes*
,[
itp), trzeba je najpierw do ucieczki, a ty lepiej po prostu robi pętlę zamiast nudnego.Przykład na żywo:
Pokaż fragment kodu
W komentarzu do pytania Martin pyta o nową
Array.prototype.map
metodę w ECMAScript5.map
nie jest to bardzo pomocne, alesome
jest:Przykład na żywo:
Pokaż fragment kodu
Masz go tylko w implementacjach zgodnych z ECMAScript5, chociaż jest to trywialne w przypadku polyfill.
Aktualizacja w 2020 r . :
some
Przykład może być prostszy dzięki funkcji strzałki (ES2015 +) i można użyćincludes
zamiastindexOf
:Przykład na żywo:
Pokaż fragment kodu
Albo nawet
bind
w to rzucić , chociaż dla mnie funkcja strzałek jest dużo bardziej czytelna:Przykład na żywo:
Pokaż fragment kodu
źródło
new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
.('disconnect'.indexOf('connect') >= 0) === true
ale('disconnect' === 'conenct') === false
'disconnect' === 'connect'
będzie to wszystko innefalse
. NieindexOf
jest też rozmyty, jest rzeczywiście bardzo jasno zdefiniowany.indexOf
dopasuje obadisconnect
iconnect
gdzie w przypadku, którego doświadczyłem, są to dwa różne przypadki, dla których chcę zwrócić wyniki w postaci warunkowej.źródło
Rozwiązanie jednoprzewodowe
Zwraca
true\false
jeśli podciągexists\does'nt exist
Potrzebuje obsługi ES6
źródło
źródło
Dla osób szukających w Google,
Solidna odpowiedź powinna brzmieć.
źródło
edycja: Jeśli kolejność testów nie ma znaczenia, możesz użyć tego (tylko z jedną zmienną pętli):
źródło
len
zmiennej, po prostu sprawdźi < arr.length
.Jeśli tablica nie jest duża, możesz po prostu zapętlić i sprawdzić ciąg z każdym podciągiem indywidualnie, używając
indexOf()
. Alternatywnie możesz skonstruować wyrażenie regularne z podciągami jako alternatywami, które mogą być bardziej wydajne lub nie.źródło
Funkcja JavaScript do przeszukiwania tablicy tagów lub słów kluczowych za pomocą ciągu wyszukiwania lub tablicy ciągów wyszukiwania. (Używa ES5 jakiś sposób tablicy i ES6 strzałka funkcje )
Przykładowe użycie:
źródło
Nie to, żebym sugerował, abyś poszedł i rozszerzył / zmodyfikował
String
prototyp, ale oto co zrobiłem:String.prototype.includes ()
źródło
Czerpiąc z rozwiązania TJ Crowdera, stworzyłem prototyp, aby poradzić sobie z tym problemem:
źródło
Za pełne wsparcie;)
źródło
Najlepsza odpowiedź brzmi: tutaj również nie jest rozróżniana wielkość liter
źródło
Używając znaku podkreślenia.js lub lodash.js, możesz wykonać następujące czynności na tablicy ciągów:
I na jednym sznurku:
źródło
Jest już bardzo późno, ale właśnie napotkałem ten problem. W moim własnym projekcie użyłem poniższego, aby sprawdzić, czy ciąg znajduje się w tablicy:
W ten sposób możesz wziąć predefiniowaną tablicę i sprawdzić, czy zawiera ciąg:
źródło
opierając się na odpowiedzi TJ Crowdera
używanie wyrażenia Escaped RegExp do testowania wystąpienia „co najmniej raz” co najmniej jednego z podciągów.
źródło
Jeśli pracujesz z długą listą podciągów składającą się z pełnych „słów” oddzielonych spacjami lub innymi popularnymi znakami, możesz być trochę sprytny w wyszukiwaniu.
Najpierw podziel ciąg na grupy X, potem X + 1, potem X + 2, ..., aż do Y. X i Y powinny być liczbą słów w podłańcuchu zawierającą odpowiednio najmniej i najwięcej słów. Na przykład jeśli X wynosi 1, a Y wynosi 4, „Alpha Beta Gamma Delta” zmienia się na:
„Alfa” „Beta” „Gamma” „Delta”
„Alpha Beta” „Beta Gamma” „Gamma Delta”
„Alpha Beta Gamma” „Beta Gamma Delta”
„Alpha Beta Gamma Delta”
Jeśli X będzie równe 2, a Y będzie 3, pominiesz pierwszy i ostatni wiersz.
Teraz możesz szybko przeszukiwać tę listę, jeśli wstawisz ją do zestawu (lub mapy), znacznie szybciej niż przez porównanie ciągów.
Wadą jest to, że nie możesz wyszukiwać podciągów, takich jak „ta Gamm”. Oczywiście możesz na to pozwolić, dzieląc się według znaków zamiast słów, ale wtedy często musiałbyś zbudować ogromny zestaw, a czas / pamięć spędzona na tym przeważają nad korzyściami.
źródło
Dla pełnego wsparcia (dodatkowo @ricca „s wersjach programu ).
źródło
Możesz sprawdzić w ten sposób:
źródło
Użyj filtra:
źródło