blue-sky
blue-sky

Reputation: 53826

Get item before filter match

To filter a list of items I use :

  val l : List[String] = List("1","a","2","b")

  l.filter(c => c.contains("b")).foreach(println)

But how can I access the items that occur before the matched item ? So in this case "2" is accessed ?

Update :

 List("1","a","2","b","3","b","4","b")
filtering on "b" returns 
List("2","3","4")
filtering on "a" returns
List("1")

Upvotes: 2

Views: 180

Answers (5)

marios
marios

Reputation: 8996

How to do this using sliding and flatMap.

val list = List("1", "2", "b", "3", "b", "b")
val target = "b"
list.sliding(2).flatMap{ 
   case Seq(x,y) => if(y == target) Some(x) else None 
   case _ => None
}.toSeq

Upvotes: 0

Puneeth Reddy V
Puneeth Reddy V

Reputation: 1568

Here is a solution

code:

 val list = List("1", "2", "b", "3", "b", "b")

 list.zip(list.tail).filter(p=>p._2 .equalsIgnoreCase("b") ).foreach(f=>println(f._1))

Upvotes: 0

Jatin
Jatin

Reputation: 31724

I think this is what you want:

val x = l.tail.foldLeft(l.head, (List.empty[(String, String)]))((x,c) => if(c.contains("b")) (c, (x._1, c):: x._2) else (c, x._2))._2

val ans = if(l.head.contains("b")) (null, l.head.contains("b")) :: x    else x

Gives you output as List((2,b)).

Upvotes: 2

Shyamendra Solanki
Shyamendra Solanki

Reputation: 8851

if you are looking for list of all items that appear just before item-that-contains-"b":

def prevItems(l: List[String]) = 
  l.sliding(2)
   .filter{ case List(a, b, _*) => b.contains("b"); case _ => false }
   .map{ x => x(0) }
   .toList

val list1 = List("1","a","2","b")
prevItems(list1)
// List(2)

val list2 = List("b", "a", "b")
prevItems(list2)
// List(a)

val list3 = List("1", "2", "b", "3", "b", "b")
prevItems(list3)
// List(2, 3, b)

Upvotes: 3

dcastro
dcastro

Reputation: 68670

Your description is a bit cryptic, but I think you want a list of the elements that appear before the first match - e.g., all elements before the first element that contains "b".

If so, use takeWhile

scala> val l = List("1","a","2","b")
l: List[String] = List(1, a, 2, b)

scala> l takeWhile {! _.contains("b")}
res0: List[String] = List(1, a, 2)

If you want the element that appears right before the first element that contains "b":

scala> l.takeWhile{! _.contains("b")}.last
res1: String = 2

Upvotes: 3

Related Questions