Ozymandias
Ozymandias

Reputation: 13

Update specific indices of Seq by another Seq in Scala

I have a first seq, for example:

val s: Seq[Double] = List.fill(6)(0.0)

and a sub sequences of the indices of s:

val subInd: Seq[Int] = List(2, 4, 5)

Now, what I want to do is update s on the positions 2, 4 and 5 by another Seq, which has the length of subInd:

val t: Seq[Double] = List(5.0, 6.0, 7.0)

such, that:

val updateBySeq(s, subInd, t): List[Double] = List(0.0, 0.0, 5.0, 0.0, 6.0, 7.0)

I have searched on this site and found Update multiple values in a sequence where the second answer comes close to the functionality I want to have.

However, the difference is, that the function provided would update s on the indices contained in subInd by one value. I, on the other hand, would want them to correspond to multiple, unique values in a third Seq t.

I have tried various things, like using recursion and ListBuffers, instead of Lists, to incrementally update the elements of s, but either they left s unchanged or I got an error because I violated some immutability constraint.

Upvotes: 1

Views: 390

Answers (1)

This should work:

def updateListByIndexes[T](data: List[T])(indexes: List[Int], update: List[T]): List[T] = {
  val updateMap = (indexes lazyZip update).toMap

  data.iterator.zipWithIndex.map {
    case (elem, idx) =>
      updateMap.getOrElse(key = idx, default = elem)
  }.toList
}

Which you can use like this:

val s = List.fill(6)(0.0)
// s: List[Double] = List(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

val subInd = List(2, 4, 5)
// subInd: List[Int] = List(2, 4, 5)

val t = List(5.0, 6.0, 7.0)
// t: List[Double] = List(5.0, 6.0, 7.0)

updateListByIndexes(s)(subInd, t)
// res: List[Double] = List(0.0, 0.0, 5.0, 0.0, 6.0, 7.0)

Upvotes: 4

Related Questions