如何将函数应用于 Scala 中的选项列表?
How to apply function to list of options in Scala?
假设我有一个函数f: (Int, Int, Int) => String
。我可以很容易地将它应用于 Option[Int]
:
类型的三个参数
def foo(f: (Int, Int, Int) => String,
ox: Option[Int],
oy: Option[Int],
oz: Option[Int]): Option[String] = ox <*> (oy <*> (oz <*> f.curried.some))
现在假设我需要将 f
应用于列表 ois: List[Option[Int]]
的前三个元素。例如:
List() => None
List(1.some, 2.some) => None
List(1.some, None, 2.some, 3.some) => None
List(1.some, 2.some, 3.some, 4.some) => Some(f(1, 2, 3))
List(1.some, 2.some, 3.some, None) => Some(f(1, 2, 3))
你会如何实施它?
您可以将 Option
、take
、flatten
和 collect
一起使用以获得一个非常干净的版本:
def foo(f: (Int, Int, Int) => String, ois: List[Option[Int]]) =
Option(ois.take(3).flatten) collect {
case List(a, b, c) => f(a, b, c)
}
如果前三个元素是 Some
,ois.take(3).flatten
只会匹配 List(a,b,c)
。您将变量包装在 Option
中以启用所需的 collect
语义(这样部分函数 miss 将 return None
和部分函数的 return将包裹在 Some
).
假设我有一个函数f: (Int, Int, Int) => String
。我可以很容易地将它应用于 Option[Int]
:
def foo(f: (Int, Int, Int) => String,
ox: Option[Int],
oy: Option[Int],
oz: Option[Int]): Option[String] = ox <*> (oy <*> (oz <*> f.curried.some))
现在假设我需要将 f
应用于列表 ois: List[Option[Int]]
的前三个元素。例如:
List() => None
List(1.some, 2.some) => None
List(1.some, None, 2.some, 3.some) => None
List(1.some, 2.some, 3.some, 4.some) => Some(f(1, 2, 3))
List(1.some, 2.some, 3.some, None) => Some(f(1, 2, 3))
你会如何实施它?
您可以将 Option
、take
、flatten
和 collect
一起使用以获得一个非常干净的版本:
def foo(f: (Int, Int, Int) => String, ois: List[Option[Int]]) =
Option(ois.take(3).flatten) collect {
case List(a, b, c) => f(a, b, c)
}
如果前三个元素是 Some
,ois.take(3).flatten
只会匹配 List(a,b,c)
。您将变量包装在 Option
中以启用所需的 collect
语义(这样部分函数 miss 将 return None
和部分函数的 return将包裹在 Some
).