Tom F
Tom F

Reputation: 453

Index of nth pattern match in Scala

I have a program where I'm attempting to find the index of the nth occurrence of the letter "e". I guessed something like this...

def findE(line: String, ignore: Int) : Int = {
    val pattern = "e".r
    val index = line.indexOf(pattern(ignore+1))
    index
}

where

ignore+1 

is the desired group, but the syntax isn't valid. Was wondering if anyone knew how to go about this?

Upvotes: 1

Views: 300

Answers (2)

Scalway
Scalway

Reputation: 1663

Here is my implementation that aims to provide a low-cost abstraction.

/** lazily finds all indices of a given char */
def indicesOf(s: String, of: Char): Iterator[Int] =
    def from(idx: Int) = s.indexOf(of, idx + 1) 
    // we use an iterator because it is extremely light!
    Iterator.iterate(from(-1))(from).takeWhile(_ >= 0)

//here is simple implementaiton of finding nth element
def indexOfNth(s: String, of:Char, n: Int) = 
    //`.slice(n, n+1).nextOption()` is needed due to lack of `.get(idx)` on iterator :(
    indicesOf(s, of).slice(n, n+1).nextOption()
  • It never iterates over the whole string to find all elements.
  • To find the nth element, we effectively call s.indexOf('\n', prevIndex) n times.
  • Only a few lightweight iterators are created to manage the process.
  • indexesOf abstraction is usefull for other cases too:
//you can implement other tools based on indexesOf also
def dropLines(s: String, x: Int) = x match
  case x if x <= 0 => s //we need to ensure that `Iterator#drop(x-1)` is stable
  case other => 
    indicesOf(s, '\n').drop(x - 1).nextOption() match
      case Some(x) => s.drop(x + 1) // default case
      case None => "" // case where we should drop more lines than exist in string

Upvotes: 0

Nicolas Rinaudo
Nicolas Rinaudo

Reputation: 6168

I'd use standard combinators if I were you.

> "abcdeabcdeabcde".zipWithIndex.collect {
    case ('e', index) => index
  }
res1: collection.immutable.IndexedSeq[Int] = Vector(4, 9, 14)

Just take whatever is at index 5, if it exists, and that's your answer.

Upvotes: 3

Related Questions