如何同时使用多个筛选器来过滤数据

不定长参数

val arr = List(111,222,333,444,555)
def sum(args:Int*):Int = args.foldLeft(0)((sum,v)=>sum+v)  // 就是args.sum求和
sum(arr:_*)  // res0: Int = 1665

不定长参数的定义(args:Int*)表示args是一个Seq[Int]序列,当调用sum函数时候传递arr参数。

筛选器
判断在arr中是否有>300的值。

def any(args:Int*):Boolean = args.exists(pred=>pred>300)
any(arr:_*)  // true

传递不定数量的函数
传递不定数量的函数做为any的参数,仿照上面传递多个Int*的写法,假设传递的函数的类型是(Int=>Boolean),意思是参数是Int,返回值是Boolean,那么传递多个函数的写法如下。

def any(args:(Int=>Boolean)*):Boolean = args.exists(pred=>pred(300))

要知道args是一个Seq序列,那么any是调用的Seq的exists方法,因为args每个元素此时都是一个(Int=>Boolean)类型的函数,那么pred=>pred(300)的意思是说调用每个函数并将300做为参数,pred就是args中的元素哦。整个定义是判断所有args中的函数在代入300后,是否有返回true的,如果有则any就返回true,否则any返回false。测试一下:

def f1:(Int=>Boolean) = one_int => one_int > 300   // 300>300
def f2:(Int=>Boolean) = one_int => one_int < 200   // 300<200
any(f1,f2)  // false

显然,上面f1和f2在传入300后都返回false,那么any就返回false。那么如何把pred=>pred(300)中的300变成可自定义的值呢,如下。

返回一个(Int=>Boolean)类型的函数
让any返回一个(Int=>Boolean)类型的函数,这将消除300的问题。

def any(args:(Int=>Boolean)*):(Int=>Boolean) = one_int => args.exists(pred=>pred(one_int))

现在any会返回一个参数类型是Int的函数。继续使用上面定义的f1和f2的定义,测试一下:

val f3 = any(f1,f2)  // 筛选出>300或<200的数
f3(300)   // false
f3(400)   // true
f3(100)   // true

any的问题解决了,但是f1和f2中的固定值也要消除的哦。同样的套路:

def f1:(Int=>(Int=>Boolean)) = 
     one_int=>
         item=>item>one_int
def f2:(Int=>(Int=>Boolean)) = 
     one_int=>
         item=>item<one_int

函数f1和f2都返回类型为(Int=>(Int=>Boolean))的函数。测试一下:

val f3 = f1(400)     // >400的数
val f4 = f2(300)     // <300的数
val f5 = any(f3,f4)  // 筛选>400或者<300的数
f5(222)  // true
f5(333)  // false
f5(444)  // true

使用type定义类型
上面的(Int=>(Int=>Boolean))定义确实够长的,那么多括号看着眼花,使用type来简化一下:

扫描二维码关注公众号,回复: 3119740 查看本文章
type IntFilter = Int=>Boolean
def f1:(Int=>IntFilter) = 
   one_int=>
       item=>item>one_int

是时候展示一个小例子了
借用上面f1到f5的定义,筛选arr中所有>400或<300的元素。

val arr = List(111,222,333,444,555)
arr.filter(f5)

啊啊啊,这完全可以用

arr.filter(_>400 || _<300)

来解决呀。好吧,这只是一个小例子。

猜你喜欢

转载自blog.csdn.net/AndCompose/article/details/82560272
今日推荐