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

不定长参数

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来简化一下:

type IntFilter = Int=>Boolean
def f1:(Int=>IntFilter) =
one_int=>

   item=>item>one_int

再看any的定义
上面得到any的定义为:

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

可以发现这个函数只能用于(Int=>Boolean)的类型,摆脱Int类型的限制是需要解决的。使用泛型:

def anyA*):(A=>Boolean) = one_a => args.exists(pred=>pred(one_a))
1
此处的[A]表示类型,在使用上并没有什么不同,完全可以用上面的例子测试。

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

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

啊啊啊,这完全可以用

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

阿里云代金券1000元免费领取地址:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=2a7uv47d
新老阿里云账户均可领取!可用于购买阿里云服务器ECS、云数据库RDS、虚拟主机、安骑士、DDoS高防IP等100多云计算产品。 代金券自领取之日起,有效期是30天,请及时使用,过30天后还可以重新领取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值