首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何简化用underscore.js编写的过滤器?

如何简化用underscore.js编写的过滤器?
EN

Stack Overflow用户
提问于 2013-08-15 19:00:43
回答 2查看 362关注 0票数 3

给定的是一个具有一系列条件的对象:

代码语言:javascript
运行
复制
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来做这件事:

代码语言:javascript
运行
复制
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 ]

它运行得很好,但不幸的是,上面的代码看起来很奇怪,而且非常混乱。

如何简化这段代码以使其更易读和更容易理解?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-15 19:17:28

这个助手函数可能很有用:

代码语言:javascript
运行
复制
_.mixin({
    invokeWith: function() {
        var args = arguments;
        return function(fn) {
             return fn.apply(null, args);
        };
    }
});

如果您的conditions立即成为一个数组,情况也会更好。您可以使用一个命名函数数组:

代码语言:javascript
运行
复制
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函数:

代码语言:javascript
运行
复制
conditions = _.values(conditions);

现在您可以将代码缩短为

代码语言:javascript
运行
复制
var result = _.filter(numbers, function(current) {
    return _.all(conditions, _.invokeWith(current));
});

理解所发生的事情可能要复杂得多,因为大多数人都必须查找invokeWith函数,但是这个概念更容易理解,因为代码非常具有声明性,包含所有用于构建自然表达式的动词,用current调用所有条件。

如果一个人也想删除外部lambda表达式,它会变得更短,但更难理解:

代码语言:javascript
运行
复制
// functional programming FTW :-)
var result = _.filter(numbers, _.compose(_.partial(_.all, conditions), _.invokeWith));
票数 4
EN

Stack Overflow用户

发布于 2013-08-15 19:06:46

没有必要重写该代码;将其放入一个命名函数中:

代码语言:javascript
运行
复制
function filterByConditions(values, conditions){
  return _.filter(values, function(current) {

    return _.all(_.values(conditions), function(f) { 
      return f(current);
    });

  });
}

函数中的代码没有那么复杂,不应该让熟悉underscore.js的人感到困惑。如果您认为有必要,可以将注释添加到函数的正文中。无论哪种方式,当您在其他地方使用该函数时,应该清楚该函数从名称中做了什么:

代码语言:javascript
运行
复制
var result = filterByConditions(numbers, conditions);

如果您想简化函数的主体,以便不熟悉underscore.js的开发人员仍然可以阅读它,那么您可以用一个简单的为了..。在……里面循环代替_all_values。大多数Javascript开发人员可以推断出.filter所做的事情,而无需使用underscore.js:

代码语言:javascript
运行
复制
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;

  });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18259740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档