Convert only the first item to a Scala list

Is there a way to convert only the first element of a list without doing something super hacks like:

val head = l1.head
val tail = l1.tail
val l2   = change(head) :: tail

updated() It looks like it can work, but is not a good improvement:

val head = l1.head
val l2   = l.update(0, change(head))

I would like something like:

val l2   = l1.updateHead(change(_))

Is there anything similar?

+5
source share
5 answers

you can try using pattern matching

val l2 = l1 match{
    case Nil   => Nil
    case x::xs => change(x)::xs
}

This way you don't have to worry if the headitem really returns

+15
source

You make your life much more difficult by introducing variables at every opportunity. Do not do that!

Both parameters that you specified are clean enough if you do not enter temporary variables:

val l2 = change(l.head) :: l.tail
val l2 = l.update(0, change(l.head))

Empty lists are also not safe, but

val l2 = l.take(1).map(change) ::: l.drop(1)

there is.

:

class ReheadableList[A](xs: List[A]) {
  def rehead[B >: A](f: A => B) = xs.take(1).map(f) ::: xs.drop(1)
}
implicit def lists_can_be_reheaded[A](xs: List[A]) = new ReheadableList(xs)

( - , ).

val l2 = l.rehead(change)
+8

Using partial lenses ( described in this article ), you can write something like:

listHeadLens.set(list, newValue)

where is listHeadLensdefined as:

def listHeadLens[A] = new PartialLens[List[A], A] {
  def apply: List[A] => Option[CoState[A, List[A]]] = {
    case Nil => None
    case x :: xs => Some(CoState(x, _ :: xs))
  }
}

I think partial lenses make their way to Scalaz 7. I'm not sure though.

+5
source

There are probably many ways to do this. Below is a Scala REPL session showing one version

scala> val change = (x: Int) => x*2
change: Int => Int = <function1>

scala> val l = List(1,2,3)
l: List[Int] = List(1, 2, 3)

scala> l.headOption.map( x => change(x) :: l.drop(1) ).getOrElse(Nil)
res3: List[Int] = List(2, 2, 3)
+3
source

You can do it like this.

val list = List("1","2","3")
def change(str : String ) = Some("x")

val nlist = (list.headOption.flatMap(change(_)).toList ::: list.tail)

in the console.

scala> val list = List("1","2","3")
list: List[java.lang.String] = List(1, 2, 3)

scala> def change(str : String ) = Some("x")
change: (str: String)Some[java.lang.String]

scala> val nlist = (list.headOption.flatMap(change(_)).toList ::: list.tail)          
nlist: List[java.lang.String] = List(x, 2, 3)
+1
source

All Articles