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
4 Answers
Reset to default 11I 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.