tkachuko tkachuko - 3 months ago 14
Scala Question

takeRightWhile() method in scala

I might be missing something but recently I came across a task to get last symbols according to some condition. For example I have a string:

. Now I want to extract

Note: number of parts separated by
is not defined.

If I would have a method
takeRightWhile(f: Char => Boolean)
on a string it would be trivial:
takeRightWhile(ch => ch != '_')
. Moreover it would be efficient: a straightforward implementation would actually involve finding the last index of
and taking a substring while the use of this method would save first step and provide better average time complexity.

UPDATE: Guys, all the variations of
are quite inefficient as you actually use additional
space. If you want to implement method
efficiently you could iterate starting from the right, accumulating result in string builder of whatever else, and returning the result. I am asking about this kind of method, not implementation which was already described and declined in the question itself.

Question: Does this kind of method exist in scala standard library? If no, is there method combination from the standard library to achieve the same in minimum amount of lines?

Thanks in advance.


Possible solution:



You can go from right to left with following expression using foldRight:

str.toList.foldRight(List.empty[Char]) {
  case (item, acc) => item::acc

Here you need to check condition and stop adding items after condition met. For this you can pass a flag to accumulated value:

val (_, list) = str.toList.foldRight((false, List.empty[Char])) {
  case (item, (false, list)) if item!='_' => (false, item::list)
  case (_,    (_,     list))              => (true, list)
val res = list.mkString.toInt

This solution is even more inefficient then solution with double reverse:

  1. Implementation of foldRight uses combination of List reverse and foldLeft

  2. You cannot break foldRight execution, so you need flag to skip all items after condition met