Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify element(s) in a list where a condition is true

case class Person(name: String, age: Int, qualified: Boolean = false)

val people: List[Person] = ....

val updated: List[Person] = people.map(person => 
  if (person.age >= 25) 
    person.copy(qualified=true) 
  else
    person  // unmodified
))

// Setting every person above 25 y.o. as qualified

Is there a combinator/higher-order-function way to do this? Like:

people.updateWhere(_.age >= 25, _.copy(qualified=true))

It's like a conditional map. Most elements pass through unmodified, but those elements who satisfy the condition are modified/"mapped-on".

like image 300
kornfridge Avatar asked Oct 31 '22 11:10

kornfridge


1 Answers

As far as I know there is no such thing, although you can make it through implicit conversion:

implicit class ListOps[A](self: List[A]) extends AnyVal {
  def updateIf(predicate: A => Boolean, mapper: A => A): List[A] = {
    self.map(el => if (predicate(el)) mapper(el) else el)
  }
}

Test:

@ case class Person(name: String, age: Int, qualified: Boolean = false)
defined class Person
@  val people = List(Person("A", 3, false), Person("B", 35, false))
people: List[Person] = List(Person("A", 3, false), Person("B", 35, false))
@ people.updateIf(_.age >= 25, _.copy(qualified=true))
res3: List[Person] = List(Person("A", 3, false), Person("B", 35, true))
like image 54
Łukasz Avatar answered Nov 04 '22 09:11

Łukasz