从集合

时间:2017-06-15 12:57:00

标签: scala collections scala-collections

让我们说我有一个Scala元素集合,以及另一个与第一个集合大小相同的布尔集合(对于好奇的读者来说,第二个集合是Ramer-Douglas-Peucker algorithm的结果) 。

现在我想从第一个集合中删除所有项目,其中第二个集合在同一个索引中具有false,一次传递,而不创建中间集合。我无法在任何可以执行此操作的Scala集合中找到任何内置方法。当然我可以写自己的,但我很惊讶Scala系列已经不是。我错过了吗?

示例:

List(1, 2, 3).removeWhere(List(false, true, false)) shouldEqual List(2) 
// removeWhere is an imaginary name for the method I'm looking for

4 个答案:

答案 0 :(得分:2)

scala> val xs = List(1,2,3).view.zip(List(true,false,true)).collect{case (x, true) => x} xs: scala.collection.SeqView[Int,Seq[_]] = SeqViewZFM(...) scala> xs.head res0: Int = 1 scala> xs.tail res1: scala.collection.SeqView[Int,Seq[_]] = SeqViewZFMS(...) 逐个处理元素。

df_joined = ugt.join(ugh, how='outer')

                      temperature    humidity                     
2017-06-13 22:06:03          82.0    63.0
2017-06-13 22:06:20          82.4    NaN
2017-06-13 22:06:21           NaN    63.0
2017-06-13 22:06:37          82.4    NaN
2017-06-13 22:06:38           NaN    63.0
2017-06-13 22:06:57          82.4    63.0

答案 1 :(得分:2)

我很无聊并且写了手册版本:

def removeWhere_(l1 : List[Int], l2 : List[Boolean], acc : List[Int] => List[Int]) : List[Int] = {
    (l1, l2) match {
      case ( x::xs, y::ys ) if y => removeWhere_(xs,ys, f => acc(x :: f))
      case ( x::xs, y::ys)       => removeWhere_(xs,ys, f => acc(f) )
      case _ => acc(List())
    }
  }

def removeWhere(l1 : List[Int], l2 : List[Boolean]) = removeWhere_(l1, l2, x => x)

不确定在创建所有函子以允许尾调用优化方面损失了多少,但它只是一次遍历。

答案 2 :(得分:1)

我不知道这是否属于"一次通过,"但你可以这样做:

val list1 = List(1, 2, 3)
val list2 = List(false, true, false)
val filtered = list1.filter(elem => list2(list1.indexOf(elem)))

但是,如果list1具有重复元素,则上述内容不足。

另一种方法,这可能违反了你的单程"要求是:

val filtered = list1.zip(list2).filter(_._2).map(_._1)

答案 3 :(得分:0)

您可以将List转换为惰性版本Stream,然后使用zipfilter

List(1, 2, 3).toStream.zip(List(false, true, false)).filter(_._2).map(_._1).toList