聊点什么
今天我们来聊聊Scala中的PartialFunction
, 以及 collect
与 PartialFunction
的完美结合
PartialFunction的定义
- 只接受一个参数
- 只处理输入数据中的一部分
- 可以定义一个
isDefinedAt
方法, 来定义可以处理的输入数据中的哪一部分, 和apply
方法
一个PartialFunction的小例子:过滤掉 None 和 odd 值, 只对 even 值求平方
private val squareSomeEvenValue: PartialFunction[Option[Int], Double] = new PartialFunction[Option[Int], Double] {
def apply(x: Option[Int]): Double = Math.sqrt(x.get)
def isDefinedAt(x: Option[Int]): Boolean = x.isDefined && x.get % 2 == 0
}
private val squareSomeEvenValue2: PartialFunction[Option[Int], Int] = {
case Some(intValue) if intValue % 2 == 0 => intValue * intValue
}
下面我们看看PartialFunction在实战中的表现
collect完美结合PartialFunction
我们定义如下一个集合 sampleSeq
, 包括 偶数(odd), 奇数(even)和None值,我们想从中挑出偶数并求其平方
private val sampleSeq = Seq(
Some(1),
Some(2),
None,
Some(3),
Some(4)
)
传统写法当然比较直接, filter + filter + map
或者 flatten + filter + map
// 传统写法1: filter + filer + map
private val filterMapSeq = sampleSeq
.filter(_.isDefined)
.filter(intValue => intValue.get % 2 == 0)
.map(squareSomeEvenValue)
// 传统写法2: flatten + filer + map
private val flattenMapSeq = sampleSeq
.flatten
.filter(intValue => intValue % 2 == 0)
.map(evenValue => evenValue * evenValue)
// map 是不支持 PartialFunction的.
Try(
sampleSeq.map(squareSomeEvenValue)
) match {
case Failure(exception) => println(exception)
} // scala.MatchError: None (of class scala.None$)
此法当然够用直接明了但不优雅, 看看下面的collect + PartialFunction
组合
// collect 支持 PartialFunction.
private val collectSeq = sampleSeq.collect(squareSomeEvenValue)
确实优雅!
言而总之
scala的PartialFunction
给到大家一块甜甜的语法糖,追求代码极致优雅简洁的朋友可以一试。当然本文只是个引子,简单聊了其基本用法。
大家可以再试试orElse and andThen
, 可以解锁更多玩法。
完整示例代码
package ddu.scala.articles
import scala.util.{Failure, Try}
object TalkAboutPartialFunction extends App {
private val sampleSeq = Seq(
Some(1),
Some(2),
None,
Some(3),
Some(4)
)
/**
* 过滤掉Seq中的None和 odd 值, 只对 even 值求平方.
* 下面是 PartialFunction 的两种写法, 当然在scala中最常用的是第二种case statement.
*
*/
private val squareSomeEvenValue: PartialFunction[Option[Int], Double] = new PartialFunction[Option[Int], Double] {
def apply(x: Option[Int]): Double = Math.sqrt(x.get)
def isDefinedAt(x: Option[Int]): Boolean = x.isDefined && x.get % 2 == 0
}
private val squareSomeEvenValue2: PartialFunction[Option[Int], Int] = {
case Some(intValue) if intValue % 2 == 0 => intValue * intValue
}
// 传统写法1: filter + filer + map
private val filterMapSeq = sampleSeq
.filter(_.isDefined)
.filter(intValue => intValue.get % 2 == 0)
.map(squareSomeEvenValue)
// 传统写法2: flatten + filer + map
private val flattenMapSeq = sampleSeq
.flatten
.filter(intValue => intValue % 2 == 0)
.map(evenValue => evenValue * evenValue)
// map 是不支持 PartialFunction的.
Try(
sampleSeq.map(squareSomeEvenValue)
) match {
case Failure(exception) => println(exception)
} // scala.MatchError: None (of class scala.None$)
// collect + PartialFunction
private val collectSeq = sampleSeq.collect(squareSomeEvenValue)
assert(collectSeq == filterMapSeq)
assert(collectSeq == flattenMapSeq)
}
标签:map,魔幻,val,Scala,Int,private,PartialFunction,intValue
From: https://blog.csdn.net/robbywt/article/details/142298557