给定的是一个具有一系列条件的对象:
var conditions = {
even: function (i) { return i % 2 == 0; },
greatherThan: function (i) { return i > 10; },
inValidRange: function (i) {
return i > 20 && i < 100;
}
};以及从0到39:var numbers = _.range(0, 40);范围内的数组数。
我想要过滤numbers的每一个条件。我用underscore.js来做这件事:
var result = _.filter(numbers, function(current) {
return _.all(_.values(conditions), function(f) {
return f(current);
});
});
// returns [ 22, 24, 26, 28, 30, 32, 34, 36, 38 ]它运行得很好,但不幸的是,上面的代码看起来很奇怪,而且非常混乱。
如何简化这段代码以使其更易读和更容易理解?
发布于 2013-08-15 19:17:28
这个助手函数可能很有用:
_.mixin({
invokeWith: function() {
var args = arguments;
return function(fn) {
return fn.apply(null, args);
};
}
});如果您的conditions立即成为一个数组,情况也会更好。您可以使用一个命名函数数组:
var conditions = [
function even(i) { return i % 2 == 0; },
function greaterThan(i) { return i > 10; },
function inValidRange(i) { return i > settings.validRange.from && i < settings.validRange.to; }
];或者在之前转换它,这样我们就可以省略(并且不需要重复调用) values函数:
conditions = _.values(conditions);现在您可以将代码缩短为
var result = _.filter(numbers, function(current) {
return _.all(conditions, _.invokeWith(current));
});理解所发生的事情可能要复杂得多,因为大多数人都必须查找invokeWith函数,但是这个概念更容易理解,因为代码非常具有声明性,包含所有用于构建自然表达式的动词,用current调用所有条件。
如果一个人也想删除外部lambda表达式,它会变得更短,但更难理解:
// functional programming FTW :-)
var result = _.filter(numbers, _.compose(_.partial(_.all, conditions), _.invokeWith));发布于 2013-08-15 19:06:46
没有必要重写该代码;将其放入一个命名函数中:
function filterByConditions(values, conditions){
return _.filter(values, function(current) {
return _.all(_.values(conditions), function(f) {
return f(current);
});
});
}函数中的代码没有那么复杂,不应该让熟悉underscore.js的人感到困惑。如果您认为有必要,可以将注释添加到函数的正文中。无论哪种方式,当您在其他地方使用该函数时,应该清楚该函数从名称中做了什么:
var result = filterByConditions(numbers, conditions);如果您想简化函数的主体,以便不熟悉underscore.js的开发人员仍然可以阅读它,那么您可以用一个简单的为了..。在……里面循环代替_all和_values。大多数Javascript开发人员可以推断出.filter所做的事情,而无需使用underscore.js:
function filterByConditions(values, conditions){
return _.filter(values, function(current){
for(condition_name in conditions){
if(!conditions[condition_name](current)){
// Condition failed
return false;
}
}
// All conditions passed
return true;
});
}https://stackoverflow.com/questions/18259740
复制相似问题