在javascript中创建简单过滤函数的最佳方法是什么?

[英]What is the best way to create simple filter functions in javascript?


Many times I face the same problem: I want to filter an array with a simple condition e.g. check for non/equality, greater than, less than, contains...

我经常遇到同样的问题:我想用简单的条件过滤数组,例如检查非/等于,大于,小于,包含...

My code looks like this:

我的代码如下所示:

var result = [1, 2, 3, 4].filter(function(i) {
   return i > 2; 
});
console.log(result); // [3, 4]

It would by nice to have shortcuts to such a simple operations so I created some helper functions:

拥有这样一个简单操作的快捷方式会很好,所以我创建了一些辅助函数:

function isGreaterThan(value) {
    return function(original) {
        return value < original;
    }
}
[1, 2, 3, 4].filter(isGreaterThan(2)); // [3, 4]

or:

要么:

function isGreaterThan(value, original) {
    return value < original;
}
[1, 2, 3, 4].filter(isGreaterThan.bind(null, 2)); // [3, 4]

Is there a better way how to do this in javascript? Does javascript have any built-in functions to support these simple comparisions?

有没有更好的方法如何在JavaScript中执行此操作? javascript是否有任何内置函数来支持这些简单的比较?

3 个解决方案

#1


4  

Madox, what you've stumbled upon is the concept of currying! And you'll be glad to hear that there is an entire JavaScript community built around that idea. With Ramda your code would look like:

Madox,你偶然发现的是currying的概念!您会很高兴听到有一个完整的JavaScript社区围绕这个想法。使用Ramda,您的代码看起来像:

var filterSmallNumbers = filter(gte(3));
var smallNumbers = filterSmallNumbers([1,2,3,4,5,6]);

And it works.

它有效。

All Ramda provides, is a list of "curried helper functions" like the one you showed. If you'd rather curry your own helper functions, then you might want a curry helper function which reduces the boilerplate: var isGreaterThan = curry(function(a, b){ return a > b }). This curry function is provided by most utility libraries like Underscore, Lodash or Ramda.

所有Ramda提供的,都是一个“curried helper functions”列表,就像你展示的那样。如果您更喜欢自己的辅助函数,那么您可能需要一个咖喱辅助函数来减少样板:var isGreaterThan = curry(函数(a,b){return a> b})。这种咖喱功能由大多数实用程序库提供,如Underscore,Lodash或Ramda。

#2


3  

I'll expand on @Avaq's answer a little bit here. You don't need a lib like Rambda to start using currying. You can start doing this with ES6 today.

我将在这里扩展@ Avaq的答案。你不需要像Rambda这样的lib来开始使用currying。您今天可以开始使用ES6。

It seems you already understand the concept here. This is already a curried function. (Each sequenced function takes only one argument)

看来你已经在这里理解了这个概念。这已经是一个curried功能。 (每个序列函数只接受一个参数)

function isGreaterThan(value) {
    return function(original) {
        return value < original;
    }
}

With ES6 arrow functions, this gets a lot easier.

使用ES6箭头功能,这将变得更加容易。

const gt = x => y => y > x;

Notice how you flipped the the operator > to a < in your function to make the usage seem more natural? It's very common with curried functions to first take the operand that is least likely to change. With gt, I think it's better to use > here since that's the name of our function, but instead flip the operands. That's why you see me returning y > x instead of x > y. gt(5) returns a function y => y > 5, which feels very natural to me.

请注意你是如何将操作符>转换为函数中的 <以使使用看起来更自然的?在curried函数中,首先采用最不可能改变的操作数是很常见的。使用gt,我认为最好使用> here,因为这是我们函数的名称,而是翻转操作数。这就是为什么你看到我返回y> x而不是x> y。 gt(5)返回一个函数y => y> 5,这对我来说很自然。

Without further ado, let's see it work in a filter

不用多说,让我们看看它在过滤器中工作

[1,2,3,4,5,6].filter(gt(3)); //=> [4,5,6]

If you need this to work in an ES5 environment, you can transpile it with babel very easily. The result should look very familiar

如果你需要在ES5环境中工作,你可以很容易地使用babel进行转换。结果看起来应该很熟悉

"use strict";
var gt = function gt(x) {
    return function (y) {
        return y > x;
    };
};

And with that, you're at the doorstep of functional programming. There's a ton of fun stuff to learn. With the kind of problem we discussed here, I think you'd be interested in learning about function composition next.

有了这个,你就在函数式编程的门口。学习有很多有趣的东西。由于我们在这里讨论的那种问题,我认为你有兴趣接下来学习功能组合。

Here's a basic composition to whet your appetite

这是一个激发你胃口的基本构成

// filter out odd numbers
const mod = x => y => y % x;
const eq = x => y => y === x;
const comp = f => g => x => f(g(x));
const isEven = comp (eq (0)) (mod (2));
[1,2,3,4,5,6].filter(isEven); //=> [2,4,6]

#3


-4  

you were almost there, here is the correct one:

你几乎在那里,这是正确的:

var original = 2;
function isGreaterThan(value) {
    return value > original;
}
var result = [1, 2, 3, 4].filter(isGreaterThan);
// result is [3, 4]

reference

参考


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2015/12/20/5697445c97f94c23c868897360dec326.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号