要获得更新了一个值的序列,可以使用
seq.updated(index, value)
我想为一系列元素设置一个新值。是否有图书馆功能?我目前使用以下功能:
def updatedSlice[A](seq: List[A], ind: Iterable[Int], value: A): List[A] =
if (ind.isEmpty) seq
else updatedSlice(seq.updated(ind.head, value), ind.tail, value)
除了编写函数之外,这似乎效率低下,并且仅适用于列表,而不是Seq
和String
的任意子类。所以,
Seq[A]
的某些子类?答案 0 :(得分:2)
计算机上没有人说过:
scala> (1 to 10).toSeq patch (3, (1 to 5), 3)
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 1, 2, 3, 4, 5, 7, 8, 9, 10)
保存@Marth的绿色支票。
请注意,他们仍在努力。
https://issues.scala-lang.org/browse/SI-8474
其中提到了一些不经常使用的API。
更新:我第二次看了一眼这个问题,看到我误解了它,哦,好吧:
scala> implicit class x[A](as: Seq[A]) {
| def updatedAt(is: collection.Traversable[Int], a: A) = {
| (as /: is) { case (xx, i) => xx updated (i, a) } } }
defined class x
scala> (1 to 10) updatedAt (Seq(3,6,9), 0)
res9: Seq[Int] = Vector(1, 2, 3, 0, 5, 6, 0, 8, 9, 0)
只是轻松一轮的高尔夫球。
更新:s / relax / annoying
看起来它需要更多类型参数,但我没有时间片。
scala> implicit class slicer[A, B[_] <: Seq[_]](as: B[A]) {
| def updatedAt[That<:B[_]](is: Traversable[Int], a: A)(implicit cbf: CanBuildFrom[B[A], A, That]) =
| (as /: is) { case (x,i) => x updated[A,That] (i,a) }}
<console>:15: error: type arguments [A,That] conform to the bounds of none of the overloaded alternatives of
value updated: [B >: _$1, That](index: Int, elem: B)(implicit bf: scala.collection.generic.CanBuildFrom[Seq[_$1],B,That])That <and> [B >: A, That](index: Int, elem: B)(implicit bf: scala.collection.generic.CanBuildFrom[Repr,B,That])That
(as /: is) { case (x,i) => x updated[A,That] (i,a) }}
^
谁知道更新过载?
我最喜欢的Odersky引用:
我玩它直到它太繁琐了。
答案 1 :(得分:1)
据我所知,没有直接提供此功能的组合器。
对于Seq
部分,它仅适用于List
,因为您将List
作为参数。拿一个Seq
,返回一个Seq
,你已经少了一个问题。
此外,如果IndexOutOfBounds
包含的索引大于或等于ind
长度,则您的实现会引发seq
异常。
这是一个替代实现(使用Set
表示O(1)contains
)
def updatedAtIndexes[A](seq: Seq[A], ind: Set[Int], value: A): Seq[A] = seq.zipWithIndex.map {
case (el, i) if ind.contains(i) => value
case (el, _) => el
}
实施例
updatedAtIndexes(List(1, 2, 3, 4, 5), Set(0, 2), 42) // List(42, 2, 42, 4)
您甚至可以使用简单的隐式类使其更漂亮:
implicit class MyPimpedSeq[A](seq: Seq[A]) {
def updatedAtIndexes(ind: Set[Int], value: A): Seq[A] = seq.zipWithIndex.map {
case (el, i) if ind.contains(i) => value
case (el, _) => el
}
}
实施例
List(1, 2, 3, 4).updatedAtIndexes(Set(0, 2), 42) // List(42, 2, 42, 4)
Vector(1, 2, 3).updatedAtIndexes(Set(1, 2, 3), 42) // Vector(1, 42, 42)