最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

how can we filter elements in array with regex in array with javascript? - Stack Overflow

programmeradmin4浏览0评论

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.

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.

Share Improve this question edited Oct 28, 2012 at 7:31 Yes Barry 9,8465 gold badges53 silver badges74 bronze badges asked Oct 28, 2012 at 7:19 user1780413user1780413 1331 gold badge1 silver badge5 bronze badges 2
  • 1 See this at stackoverflow.com/questions/13107048/… – I am Andy Commented Oct 28, 2012 at 7:38
  • 1 @IamAndy how is that question remotely relevant to this one? – Alnitak Commented Oct 28, 2012 at 8:35
Add a comment  | 

4 Answers 4

Reset to default 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)

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/

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/

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.

发布评论

评论列表(0)

  1. 暂无评论