用scala替换List中的元素

Ber*_*own 50 replace scala

如何使用不可变List替换索引元素.

例如

val list = 1 :: 2 ::3 :: 4 :: List()

list.replace(2, 5)
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 89

如果要替换索引2,那么

list.updated(2,5)    // Gives 1 :: 2 :: 5 :: 4 :: Nil
Run Code Online (Sandbox Code Playgroud)

如果你想找到每个有2的地方而不是放入5,

list.map { case 2 => 5; case x => x }  // 1 :: 5 :: 3 :: 4 :: Nil
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,你并没有真正"替换",而是返回一个新的列表,该列表在那些(那些)位置具有不同的元素.


Vas*_*iuk 51

除了之前的说法,您还可以使用patch替换序列子序列的函数:

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

scala> list.patch(2, Seq(5), 1) // replaces one element of the initial sequence
res0: List[Int] = List(1, 2, 5, 4)

scala> list.patch(2, Seq(5), 2) // replaces two elements of the initial sequence
res1: List[Int] = List(1, 2, 5)

scala> list.patch(2, Seq(5), 0) // adds a new element
res2: List[Int] = List(1, 2, 5, 3, 4)
Run Code Online (Sandbox Code Playgroud)


Ken*_*oom 9

你可以使用list.updated(2,5)(这是一种方法Seq).

scala.collection.immutable.Vector为了这个目的,使用a可能更好,因为Vector采取(我认为)恒定时间的更新.

  • 不是很恒定的时间,而是具有大基数的对数(在实践中足够接近"具有相当大的常数的恒定时间"). (5认同)
  • 矢量是'O((日志大小)/ 32)`.实际上,它接受的最大嵌套级别数为6,每个嵌套级别有32个元素.因此,对于可能的最大集合,您必须复制6*32元素.如果您确定只会更新前几个元素,那么更新"List"可能会获胜,但很快就会失去任何优势.至于查找,有http://www.scala-lang.org/docu/files/collections-api/collections_40.html,但您也可以通过Scaladoc上的链接检查实现本身. (4认同)
  • 另一点是`Vector`具有良好的引用空间局部性,因此它对缓存友好.另一方面,`List`具有非常差的参考局部性. (3认同)
  • @Alexey对于`Vector`的`更新'不依赖于索引,而不是`List`上的`updated`,它是`O(index)`.这使得固定大小的集合真正保持不变,这可能很适用.我不是否认你说的话,但我认为这是一个有趣的观点. (2认同)