【问题标题】:Replace element in List with scala用 scala 替换 List 中的元素
【发布时间】:2011-07-01 01:13:46
【问题描述】:

如何用不可变列表按索引替换元素。

例如

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

list.replace(2, 5)

【问题讨论】:

    标签: scala replace


    【解决方案1】:

    如果要替换索引2,那么

    list.updated(2,5)    // Gives 1 :: 2 :: 5 :: 4 :: Nil
    

    如果你想找到所有有 2 的地方,然后把 5 放进去,

    list.map { case 2 => 5; case x => x }  // 1 :: 5 :: 3 :: 4 :: Nil
    

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

    【讨论】:

      【解决方案2】:

      你可以使用list.updated(2,5)(这是Seq上的一个方法)。

      为此目的使用scala.collection.immutable.Vector 可能会更好,因为Vector 的更新需要(我认为)恒定时间。

      【讨论】:

      • 不是恒定的时间,而是具有大底的对数(在实践中足够接近“具有相当大常数的恒定时间”)。
      • @Alexey Vector 上的updated 不依赖于索引,而List 上的updated 则为O(index)。这使得固定大小的集合的时间非常恒定,这很可能适用。我不否认你所说的,但我认为这是一个有趣的观点。
      • @Daniel:那么说List 上的updatedO(index)Vector 上的updatedO(lg size) 是否正确,这可能使List 在以下情况下具有优势size 很大,但index 很小? (我很想知道在哪里可以找到有关 Scala 不可变结构的时间保证的更多信息。)
      • 向量是O((log size)/32)。实际上,它接受的最大嵌套层数是 6,每层有 32 个元素。因此,对于可能的最大集合,您必须复制 6 * 32 个元素。如果您确定只有前几个元素会被更新,那么更新List 可能会成功,但它很快就会开始失去任何优势。至于查找它,有 scala-lang.org/docu/files/collections-api/collections_40.html,但您也可以通过 Scaladoc 上的链接检查实现本身。
      • 还有一点是Vector具有良好的空间参考局部性,所以它是缓存友好的。另一方面,List 的引用位置很差。
      【解决方案3】:

      除了前面说的,还可以使用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)
      

      【讨论】:

        【解决方案4】:

        如果你做了很多这样的替换,最好使用可变类或数组。

        【讨论】:

        • 还有很多其他的... 问题 ...使用可变数据结构会带来很多问题,所以在决定使用它们之前,请确保您已经意识到这一点。
        • 我同意存在问题。但是对于可变数据使用非可变数据结构也存在问题。
        【解决方案5】:

        您可以使用 map 生成一个新列表,如下所示:

        @ list
        res20: List[Int] = List(1, 2, 3, 4, 4, 5, 4)
        @ list.map(e => if(e==4) 0 else e)
        res21: List[Int] = List(1, 2, 3, 0, 0, 5, 0)
        

        【讨论】:

          【解决方案6】:

          也可以使用patch function as来实现

          scala> var l = List(11,20,24,31,35)
          
          l: List[Int] = List(11, 20, 24, 31, 35)
          
          scala> l.patch(2,List(27),1)
          
          res35: List[Int] = List(11, 20, 27, 31, 35)
          

          其中 2 是我们要添加值的位置,List(27) 是我们要添加到列表中的值,1 是要从原始列表中替换的元素数。

          【讨论】:

            【解决方案7】:

            下面是一个简单的scala List中字符串替换的例子,你可以对其他类型的数据做类似的操作

                scala> val original: List[String] = List("a","b")
            
                original: List[String] = List(a, b)
            
                scala> val replace = original.map(x => if(x.equals("a")) "c" else x)
            
                replace: List[String] = List(c, b)
            

            【讨论】:

            • cols 来自哪里?这个答案与 damon-lin 两年前的答案有何不同?
            猜你喜欢
            • 2017-03-15
            • 2018-12-02
            • 1970-01-01
            • 2019-10-25
            • 1970-01-01
            • 1970-01-01
            • 2015-11-28
            • 2010-09-08
            • 2019-12-20
            相关资源
            最近更新 更多