How to effectively get indices of 1s for given binary string using Scala?

Suppose we have a binary string such as 10010010.

All I want is a function returning indices of 1s for that string:

indicesOfOnes("10010010") -> List(0, 3, 6)
indicesOfOnes("0") -> List()

And what I implemented is:

def indicesOfOnes(bs: String): List[Int] = {
  val lb = ListBuffer[Int]()
  bs.zipWithIndex.foreach { case (v, i) =>
    if (v == '1') {
      lb += i

This works, but I think there're much better (more functional) ways to do this job. Any advices would be appreciated.


You can use a filter and then map to get the index :

scala> val s = "10010010"
s: String = 10010010

scala> s.zipWithIndex.withFilter(_._1 == '1').map(_._2)
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 3, 6)

Note: I'm using withFilter and not filter to avoid creating a temporary collection.

Or you can use collect, which applies a partial function on the elements over which it is defined:

scala> s.zipWithIndex.collect { case (char, index) if char == '1' => index }
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 3, 6)


 ? Not clear about the "Checked exception" explanation in "functional programming in Scala"
 ? React Router with nested children?
 ? get route in menu bootstrap react highlight
 ? Understanding how to have multiple pages with React and react-router
 ? How does the key argument to sorted work?
 ? How does the key argument to sorted work?
 ? How does the key argument to sorted work?
 ? Python3: sorting a list of dictionary keys
 ? How does the key argument in python's sorted function work?
 ? writing a recursive function to count the depth of a tree