2012-10-28 10 views
6

Załóżmy, że mam dwie tablice: jedna to wyrażenie regularne, a druga to dane wejściowe. Jaki jest zatem najlepszy sposób - pod względem wydajności i czytelności - na zrobienie czegoś takiego jak wyjście?jak możemy filtrować elementy w tablicy za pomocą wyrażeń regularnych w tablicy z javascript?

var regex = [ 
    '/rat/', 
    '/cat/' 
    '/dog/', 
    '/[1-9]/' 
] 

var texts = [ 
    'the dog is hiding', 
    'cat', 
    'human', 
    '1' 
] 

końcowy wynik jest

result = [ 
    'human' 
] 

No, co myślałem żeby zrobić coś takiego reduce:

// loop by text 
for (var i = texts.length - 1; i >= 0; i--) { 
    // loop by regex 
    texts[i] = regex.reduce(function (previousValue, currentValue) { 
     var filterbyRegex = new RegExp("\\b" + currentValue + "\\b", "g"); 
     if (previousValue.toLowerCase().match(filterbyRegex)) { 
      delete texts[i]; 
     }; 
     return previousValue; 
    }, texts[i]); 
} 

jednak, że nie jest czytelny? Może jest inny sposób, o którym nie pomyślałem.

+1

Zobacz to na http://stackoverflow.com/questions/13107048/javascript-desconstrutioning-menu –

+1

@IamAndy jak to pytanie jest zdalnie związane z tym? – Alnitak

Odpowiedz

7

to pewnie wyglądać następująco

var regexs = [ 
    /rat/i, 
    /cat/i, 
    /dog/i, 
    /[1-9]/i 
] 

var texts = [ 
    'the dog is hiding', 
    'cat', 
    'human', 
    '1' 
] 

var goodStuff = texts.filter(function (text) { 
    return !regexs.some(function (regex) { 
     return regex.test(text); 
    }); 
}); 

Ale realistycznie, różnice w wynikach są tak znikome tutaj, chyba że jesteś robi to 10 000 razy.

Należy pamiętać, że ta wykorzystuje metody ES5, które są łatwo shimmable (wymyśliłem słowo wiem)

+0

dobre wykorzystanie '.some' - zapomniałem o tym. – Alnitak

+0

Dzięki bro, zauważyłem, że większość funkcji macierzy można znaleźć za pomocą mniej powszechnych istniejących metod lub głębszego ich wykorzystania. Są bardzo potężni. Rekwizyty dla chłopców ECMA –

+0

były uczciwe, większość z tych metod została zaczerpnięta z funkcjonalnych języków programowania, w których funkcje manipulujące listami są kluczowe dla języka. – Alnitak

1

Oczywiście musisz przetworzyć tekst w tablicy elemnt według elementu. Jednak możesz połączyć wyrazy regularne w jeden, łącząc się z "|"

Wyświetlona tablica regexps to w rzeczywistości proste ciągi. Chciałbym usunąć znaki wiodące i końcowe/znaki, a następnie skonstruować pojedyncze wyrażenie regularne. Coś jak:

function reduce (texts, re) { 
    re = new RegExp (re.join ('|')); 
    for (var r = [], t = texts.length; t--;) 
    !re.test (texts[t]) && r.unshift (texts[t]); 
    return r; 
} 

alert (reduce (['the dog is hiding', 'cat', 'human', '1'], ['rat', 'cat', 'dog', '[1-9]'])) 

Należy pamiętać, że jeśli ciągi re zawierają znaki specjalne RegExp podoba {[^ $ etc trzeba będzie uciec je albo w struny lub przetworzyć je w funkcji..

See jsfiddle: http://jsfiddle.net/jstoolsmith/D3uzW/

+0

ta odpowiedź również nie jest rozróżniana wielkości liter ani nie szuka granic słów – Alnitak

2

Oto moje rozwiązanie:

var words = [ 'rat', 'cat', 'dog', '[1-9]' ]; 

var texts = [ ... ]; 

// normalise (and compile) the regexps just once 
var regex = words.map(function(w) { 
    return new RegExp('\\b' + w + '\\b', 'i'); 
}); 

// nested .filter calls, removes any word that is 
// found in the regex list 
texts = texts.filter(function(t) { 
    return regex.filter(function(re) { 
     return re.test(t); 
    }).length === 0; 
}); 

http://jsfiddle.net/SPAKK/

0

tylko pomysł, połączyć regex tablicy do nowej regex i połączyć drugą tablicę do nowego łańcucha każda wartość jest dzielona sygnałem, na przykład @, #, a następnie użyj wyrażenia regularnego, aby zastąpić część dopasowania.

Powiązane problemy