产生ignore()值("平均收益率")

时间:2014-05-15 21:13:43

标签: scala

我有一张地图,我希望通过yield将其转换为新的集合,并根据键进行过滤。我只希望地图条目的子集在新集合中。

scala> val the_map = Map(1->10, 2->41, 3->41, 27->614, 400->541, 5214 -> 2)
the_map: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 41, 27 -> 614, 3 -> 41, 400 -> 541)

scala> val transformed = for ((k, v) <- the_map) yield {if (k < 10) { v * 10 } else if (k > 100 && k < 400) { v * 5 }}
transformed: scala.collection.immutable.Iterable[AnyVal] = List(100, 410, (), 410, 2705, ())

所以我基本上想要那个,但是没有()s,并且类型是Iterable [Int]。这里有什么正确的方法?我可以过滤删除()然后施放,但这似乎是错误的。我可以将所有的值都放在底部,然后调用flatten,但这似乎过分了。有干净的路吗?我只想要yield忽略if语句匹配时返回的()&#。

3 个答案:

答案 0 :(得分:5)

flatMap是要走的路:

val transformed =
  the_map.flatMap {
    case (k, v) =>
      if (k < 10)
        Some(v * 10)
      else if (k > 100 && k < 400)
        Some(v * 5)
      else None
  }

您也可以使用折叠明确地执行此操作(尽管我发现它不如flatMap方法明确):

val transformed2 =
  the_map.foldLeft(Vector.empty[Int]) {
    case (z, (k, v)) =>
      if (k < 10)
        z :+ (v * 10)
      else if (k > 100 && k < 400)
        z :+ (v * 5)
      else z
  }

答案 1 :(得分:3)

collect采用部分函数,​​只返回定义部分函数的值。

val theMap = Map(1->10, 2->41, 3->41, 27->614, 400->541, 5214->2)

val res = theMap.collect({
  case (k, v) if k < 10 => v * 10
  case (k, v) if k > 100 && k < 400 => v * 5
})

res // List(100, 410, 410)

答案 2 :(得分:0)

首先,我想知道你从哪里得到你的2705 ...如果我粘贴你的代码,我的结果是:

transformed: scala.collection.immutable.Iterable[AnyVal] = List((), 100, 410, (), 410, ())

不是

transformed: scala.collection.immutable.Iterable[AnyVal] = List(100, 410, (), 410, 2705, ())
在这种情况下,dhg的答案可能是最好的,因为在理解和产量方面的重复条件可能比较难以阅读。如果您选择,可以这样表达,如下:

val transformed = 
    for( (k,v) <- the_map if k < 10 || (k > 100 && k < 400) ) 
    yield if (k < 10) v*10 else v*5
transformed: scala.collection.immutable.Iterable[Int] = List(100, 410, 410)