Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 从集合中删除所有索引_Scala_Collections_Scala Collections - Fatal编程技术网

Scala 从集合中删除所有索引

Scala 从集合中删除所有索引,scala,collections,scala-collections,Scala,Collections,Scala Collections,假设我有一个Scala元素集合和另一个布尔值集合,对于好奇的读者来说,与第一个集合的大小相同,第二个集合是 现在,我想删除第一个集合中的所有项,其中第二个集合在同一个索引中具有false,只需一次,而不创建中间集合。我在任何Scala集合上都找不到任何可以实现这一点的内置方法。当然我可以自己写,但我很惊讶Scala collections还没有。我只是错过了吗 例如: List(1, 2, 3).removeWhere(List(false, true, false)) shouldEqual

假设我有一个Scala元素集合和另一个布尔值集合,对于好奇的读者来说,与第一个集合的大小相同,第二个集合是

现在,我想删除第一个集合中的所有项,其中第二个集合在同一个索引中具有false,只需一次,而不创建中间集合。我在任何Scala集合上都找不到任何可以实现这一点的内置方法。当然我可以自己写,但我很惊讶Scala collections还没有。我只是错过了吗

例如:

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

我不知道这是否符合单次通过的条件,但您可以:

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)

我不知道这是否符合单次通过的条件,但您可以:

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)
逐个查看流程元素

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(...)
逐个查看流程元素

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(...)

我觉得很无聊,于是写了手册:

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)

不确定创建所有functor以允许尾部调用优化会损失多少,但这只是一次遍历。

我很无聊,编写了手动版本:

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)
不确定创建所有函数以允许尾部调用优化会损失多少,但这只是一次遍历。

您可以将列表转换为其惰性对应项流,然后使用zip和筛选器:

您可以将列表转换为其惰性对应项流,然后使用zip和筛选器:


它是二次型的,但对于短列表仍然很有效,例如在一个示例中。zip解决方案是线性的,而且更短!。zip版本绝对更好——不要忘记list1.indexOf本身就是线性的。两次通过应该是可以的。它是二次的,但是对于短列表仍然可以很好地工作,比如在一个例子中。zip解决方案是线性的,而且更短!。zip版本绝对更好——不要忘记list1.indexOf本身就是线性的。两次传球就可以了。