7 votes

comment filtrer les éléments d'un tableau avec regex dans un tableau avec javascript ?

Disons que j'ai deux tableaux : l'un est la regex et l'autre est l'entrée. Quelle est alors la meilleure façon - en termes de performance et de lisibilité - de faire quelque chose comme la sortie ?

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

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

le résultat final est

result = [
    'human'
]

Eh bien, je pensais faire quelque chose comme 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]);
}

Mais, n'est-ce pas lisible ? Il existe peut-être un autre moyen auquel je n'ai pas pensé.

10voto

Roderick Obrist Points 3450

Je ferais probablement quelque chose comme ça

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);
    });
});

Mais d'un point de vue réaliste, les différences de performances sont tellement négligeables ici, sauf si vous le faites 10 000 fois.

Veuillez noter que ceci utilise des méthodes ES5, qui sont facilement shimmable (j'ai inventé un mot que je connais)

3voto

Alnitak Points 143355

Voici ma solution :

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/

1voto

HBP Points 6676

Il est clair que vous devez traiter le tableau de textes élément par élément. Cependant, vous pouvez combiner vos regexps en une seule en les joignant avec '|'.

Le tableau de regexps que vous montrez est en fait une simple chaîne de caractères. J'enlèverais les caractères / de tête et de queue, puis je construirais une seule regexp. Quelque chose comme :

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]']))

Sachez que si vos chaînes re contiennent des caractères spéciaux RegExp tels que .{[^$], vous devrez les échapper soit dans les chaînes, soit en les traitant dans la fonction.

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

0voto

OQJF Points 1078

Juste une idée, combinez le tableau de regex à une nouvelle regex et combinez le second tableau à une nouvelle chaîne, chaque valeur est séparée par un signal, comme @ ,#, puis utilisez la regex pour remplacer la partie correspondante.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X