8

Let's say I have two arrays: one is the regex and the other one is the input. What, then, is the best way - in terms of performance and readability - to do something like the output?

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

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

the end result is

result = [
    'human'
]

Well, what I was thinking was to do something like 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]);
}

But, is that not readable? Maybe there is another way that I haven't thought of.

2
  • 1
    See this at stackoverflow.com/questions/13107048/… Commented Oct 28, 2012 at 7:38
  • 1
    @IamAndy how is that question remotely relevant to this one? Commented Oct 28, 2012 at 8:35

4 Answers 4

11

I would probably go something like this

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

But realistically, performance differences are so negligible here unless you are doing it 10,000 times.

Please note that this uses ES5 methods, which are easily shimmable (I made up a word I know)

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks bro, I've noticed that most array functionality can be found with the less common existing methods, or deeper use of them. They are very powerful. props to ECMA boys
to be fair, most of those methods were pinched from functional programming languages where functions that manipulate lists are core to the language.
p.s. you probably ought to explain how this works, and why it's more efficient than mine...
I could not do a better job of that Mozilla already have. google MDN array.some, MDN array.filter, MDN regexp.test
I was only talking about .some - the rest is obvious ;-) BTW, what you haven't done is test for word boundaries and make it case insensitive, per the OP's code...
|
3

Here's my 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/

Comments

1

You clearly have to process the texts array elemnt by element. However you could combine your regexps into a single one by joining with '|'

The regexps array you show are actually simple strings. I would remove the leading and trailing / characters and then construct a single regexp. Something like :

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

Be aware that if your re strings contain RegExp special characters like .{[^$ etc you will need to escape them either in the strings or process them in the function.

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

1 Comment

this answer also fails to be case insensitive or look for word boundaries
0

Just an idea, combine the regex array to a new regex and combine the second array to a new string, every value is split with an signal, such as @ ,#, then use regex to replace the match part.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.