除了第一个负数之外,如何从Seq中删除负数?

时间:2016-02-04 08:42:44

标签: scala

如何从序列中删除所有负数,但第一个负数除外。我不确定如何保留第一个负数,然后删除其他负数。

def negativeNumbers(sequence: Iterable[Int]): Iterable[Int] = {
   sequence.filter(_ > 0)
   return sequence
}

negativeNumbers(Seq(6, 2, -4, 7, 9, 10, -15, 8, -20))

执行后我应该得到Seq(6,2,-4,7,9,10,8)

因为-4是FIRST负数,这意味着它没有被删除,但其他负数被删除。

5 个答案:

答案 0 :(得分:1)

span让你关闭:

scala> val vs = Seq(6, 2, -4, 7, 9, 10, -15, 8, -20)
vs: Seq[Int] = List(6, 2, -4, 7, 9, 10, -15, 8, -20)

scala> val (pos, rest) = vs span (_ >= 0)
pos: Seq[Int] = List(6, 2)
rest: Seq[Int] = List(-4, 7, 9, 10, -15, 8, -20)

scala> (pos :+ rest.head) ++ (rest.tail filter (_ >= 0))
res0: Seq[Int] = List(6, 2, -4, 7, 9, 10, 8)

编辑:

scala> def f(vs: Iterable[Int]) = {
     | val (pos, rest) = vs span (_ >= 0)
     | (pos ++ rest.headOption) ++ (rest drop 1 filter (_ >= 0))
     | }
f: (vs: Iterable[Int])Iterable[Int]

scala> f(List(1,2,3))
res9: Iterable[Int] = List(1, 2, 3)

scala> f(vs)
res10: Iterable[Int] = List(6, 2, -4, 7, 9, 10, 8)

答案 1 :(得分:0)

你可以做到

seq.foldLeft(false -> List.empty[Int]) {
  case ((true, ls), neg) if (neg < 0) =>
    true -> ls // after firstFound=true
  case ((false, ls), neg) if (num < 0) =>
    true -> (ls :+ neg)
  case ((firstFound, ls), positive) =>
    first -> (ls :+ positive)
}._2 // get just List from last state

答案 2 :(得分:0)

将列表拆分为带有非负元素的前导位和其余的(如果非空,则必须以负数开头)。从其余的

中删除其他负数
def negativeNumbers(sequence: Iterable[Int]): Iterable[Int] = {
    val (before, after) = sequence.span(_>=0)

    if (after.isEmpty) before else before ++ Iterable(after.head) ++ after.tail.filter(_>=0)
   } 

答案 3 :(得分:0)

val seq = Seq(6, 2, -4, 7, 9, 10, -15, 8, -20)
val neg = seq.filter{a => a<0}
seq.filter{ b => b>0 || b == neg.headOption.getOrElse(-1)}

答案 4 :(得分:0)

我的方法是使用scanLeft跟踪是否找到第一个负数,然后收集结果:

val s = Seq(6, 2, -4, 7, 9, 10, -15, 8, -20)
s.zip(s.scanLeft(true){
  (b,i) => b && i >= 0
}).collect{
  case (i,b) if b || i >= 0 => i
}