在scala中解压映射操作中的选项字段的最佳方法

在scala中解压映射操作中的选项字段的最佳方法,scala,Scala,假设我有一个元组列表: val xs: List[(Seq[String], Option[String])] = List( (Seq("Scala", "Python", "Javascript"), Some("Java")), (Seq("Wine", "Beer"), Some("Beer")), (Seq("Dog", "Cat", "Man"), None) ) 以及一个函数,如果字符串在字符串序列中,则返回该字符串的索引: def getIndex(s: Seq

假设我有一个元组列表:

val xs: List[(Seq[String], Option[String])] = List(
  (Seq("Scala", "Python", "Javascript"), Some("Java")),
  (Seq("Wine", "Beer"), Some("Beer")),
  (Seq("Dog", "Cat", "Man"), None)
  )
以及一个函数,如果字符串在字符串序列中,则返回该字符串的索引:

def getIndex(s: Seq[String], e: Option[String]): Option[Int] = 
  if (e.isEmpty) None
  else Some(s.indexOf(e.get))
现在,我试图用getIndex映射xs,并只返回那些我找到有效索引的。一种方法如下:

xs.map{case (s, e) => {
  val ii = getIndex(s, e) // returns an Option
  ii match {  // unpack the option
    case Some(idx) => (e, idx)
    case None => (e, -1) // give None entries a placeholder with -1
  }
}}.filter(_._2 != -1) // filter out invalid entries
这种方法对我来说非常冗长和笨拙。flatMap在这里不起作用,因为我返回的是一个元组,而不仅仅是索引。这样做的惯用方法是什么?

map和getOrElse可能会让事情变得更清楚一些:

// use map you will get Some(-1) if the element doesn't exist or None if the element is None
xs.map{case (s, e) => (e, e.map(s.indexOf(_)))}.

// check if the index is positive and use getOrElse to return false if it's None
   filter{case (e, idx) => idx.map(_ >= 0).getOrElse(false)}

// res16: List[(Option[String], Option[Int])] = List((Some(Beer),Some(1)))
或:

map和getOrElse可能会让事情更清楚一些:

// use map you will get Some(-1) if the element doesn't exist or None if the element is None
xs.map{case (s, e) => (e, e.map(s.indexOf(_)))}.

// check if the index is positive and use getOrElse to return false if it's None
   filter{case (e, idx) => idx.map(_ >= 0).getOrElse(false)}

// res16: List[(Option[String], Option[Int])] = List((Some(Beer),Some(1)))
或:

A是实现这一目标的一种方法:

scala> val xs: List[(Seq[String], Option[String])] = List(
  (Seq("Scala", "Python", "Javascript"), Some("Java")),
  (Seq("Wine", "Beer"), Some("Beer")),
  (Seq("Dog", "Cat", "Man"), None)
)
xs: List[(Seq[String], Option[String])] = List((List(Scala, Python, Javascript),Some(Java)), (List(Wine, Beer),Some(Beer)), (List(Dog, Cat, Man),None))

scala> def getIndex(seq: Seq[String], e: Option[String]): Option[Int] =
  e.map(seq.indexOf(_)).filter(_ != -1) // notice we're doing the filter here
getIndex: getIndex[](val seq: Seq[String],val e: Option[String]) => Option[Int]

scala> for {
  (seq, string) <- xs
  index <- getIndex(seq, string)
  s <- string
} yield (s, index)
res0: List[(String, Int)] = List((Beer,1))
A是实现这一目标的一种方法:

scala> val xs: List[(Seq[String], Option[String])] = List(
  (Seq("Scala", "Python", "Javascript"), Some("Java")),
  (Seq("Wine", "Beer"), Some("Beer")),
  (Seq("Dog", "Cat", "Man"), None)
)
xs: List[(Seq[String], Option[String])] = List((List(Scala, Python, Javascript),Some(Java)), (List(Wine, Beer),Some(Beer)), (List(Dog, Cat, Man),None))

scala> def getIndex(seq: Seq[String], e: Option[String]): Option[Int] =
  e.map(seq.indexOf(_)).filter(_ != -1) // notice we're doing the filter here
getIndex: getIndex[](val seq: Seq[String],val e: Option[String]) => Option[Int]

scala> for {
  (seq, string) <- xs
  index <- getIndex(seq, string)
  s <- string
} yield (s, index)
res0: List[(String, Int)] = List((Beer,1))

有很多方法可以做到这一点。其中之一是:

val result = xs.flatMap { tuple =>
  val (seq, string) = tuple
  string.map(s => (s, seq.indexOf(s))).filter(_._2 >= 0)
}

有很多方法可以做到这一点。其中之一是:

val result = xs.flatMap { tuple =>
  val (seq, string) = tuple
  string.map(s => (s, seq.indexOf(s))).filter(_._2 >= 0)
}

也许这看起来更为惯用:

  val two = xs.filter {case (s, e) => e.isDefined}
    .map {case (s, e) => (e, s.indexOf(e.get)) }
    .filter {case (e, i) => i > 0}

也许这看起来更为惯用:

  val two = xs.filter {case (s, e) => e.isDefined}
    .map {case (s, e) => (e, s.indexOf(e.get)) }
    .filter {case (e, i) => i > 0}
我们可以使用collect方法来组合映射和过滤器:

我们可以使用collect方法来组合映射和过滤器:


你可以使用平面地图。在某些情况下返回列表e、idx和无情况返回列表NIL中,可以使用flatMap。在Some case返回列表e、idx和None case返回NilSo close:xs.collect{cases s,如果s.containse=>s,s.indexOfe}那么close:xs.collect{case s,如果s.containse=>s,s.indexOfe}