ps0604
ps0604

Reputation: 1071

Removing an element from Seq

In this code, given a structure Seq[Seq[String]] I'm trying to get rid of element "B" in each sequence. To do that, my intent is to replace the field with None and then flatten the Seq. Problem is that the flatten statement does not compile, why is that and how to fix this?

 object HelloScala extends App{

      Seq(Seq("A","B","C"),Seq("A","B","C")).map{ rec =>
          val rec2 = rec.zipWithIndex.map{ case (field, i) =>
                    if (field == "B")
                        None
                    else
                        field + i
          }
          println(rec2.flatten)
      }
 }

Upvotes: 2

Views: 7120

Answers (4)

Mahmoud Hanafy
Mahmoud Hanafy

Reputation: 1897

You can use diff function. For ex.

scala> Seq("a", "b", "c").diff(Seq("b"))
res1: Seq[String] = List(a, c)

Upvotes: 0

jwvh
jwvh

Reputation: 51271

  1. The result of an assignment is Unit. Not what you want in a map().

  2. The compliment of None is Some(), which you'll want to use to keep the result type consistent.

  3. map() followed by flatten can be combined in a flatMap().

-

Seq(Seq("A","B","C"),Seq("A","B","C")).map { rec =>
  rec.zipWithIndex.flatMap { case (field, i) =>
    if (field == "B")
      None
    else
      Some(field + i)
  }
}
//res0: Seq[Seq[String]] = List(List(A0, C2), List(A0, C2))

Upvotes: 2

Andrey Tyukin
Andrey Tyukin

Reputation: 44918

I'm not sure why you are trying to do something that simple in such a convoluted way. Here is the code inferred from your description:

val withoutB = Seq(Seq("A","B","C"),Seq("A","B","C")).map{ _.filterNot(_ == "B")}
val flattened = withoutB.flatten

println(withoutB)
println(flattened)

prints:

List(List(A, C), List(A, C))
List(A, C, A, C)

In the hope that it helps to understand your mistake, I've forced your code snippet to compile, annotated it with additional types of all intermediate results, and printed them out:

val withNones: Seq[Seq[Any]] = Seq(Seq("A","B","C"),Seq("A","B","C")).map{ rec =>
  val rec2: Seq[Any] = rec.zipWithIndex.map{ case (field, i) =>
    if (field == "B")
        None
    else
        field + i
  }
  rec2
}

val flattenedWithNones: Seq[Any] = withNones.flatten

println(withNones)
println(flattenedWithNones)

it prints:

List(List(A0, None, C2), List(A0, None, C2))
List(A0, None, C2, A0, None, C2)

but this is most likely not what you wanted.

Upvotes: 2

airudah
airudah

Reputation: 1179

Here:

scala> Seq(Seq("A","B","C"),Seq("A","B","C")).flatten.filterNot(_ == "B")
res0: Seq[String] = List(A, C, A, C)

Upvotes: 1

Related Questions