I'd like to suggest an alternative solution without string manipulation at all. Instead you can combine functions. Building up code through function composition rather than string manipulation should be less error-prone - and surely less 'hacky' (whatever that means exactly...).
Javascript has first-order functions, you can just pass around (and combine) predicates. A predicate is a function which returns a boolean. For example:
var isLabelTest = function(obj) {
return obj.label === 'test';
}
Rather than storing conditions as strings, you can store them as predicate functions.
Then you can write some functions which take predicates and return new predicates:
var binaryAnd = function(predA, predB) {
return function(obj) {
return predA(obj) && predB(obj);
};
};
var binaryOr = function(predA, predB) {
return function(obj) {
return predA(obj) || predB(obj);
};
};
You could also write functions which take an array of predicates and combine all predicates in the array into a new predicate:
var and = function(preds) {
return preds.reduce(binaryAnd, function(obj) {return true;});
};
var or = function(preds) {
return preds.reduce(binaryOr, function(obj) {return false;});
};
Now given an "andArray" of predicates which all need to return true, and an "orArray" of predicates of which at least one needs to return true, the following code does the job:
var results = [];
var combinedPredicate = binaryAnd(and(andArray), or(orArray));
var pushIfCondition = function (obj) {
results.push(combinedPredicate(obj));
};
dataArray.forEach(pushIfCondition);
Finally, note that it is not necessary to write those functions for combining predicates yourself, libraries like ramda can provide more efficient implementations.