Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在列表的指定位置插入新元素_Scala - Fatal编程技术网

Scala 在列表的指定位置插入新元素

Scala 在列表的指定位置插入新元素,scala,Scala,列表中没有内置函数或方法允许用户在列表的某个位置添加新元素。我已经编写了一个函数来实现这一点,但我不确定这样做是否是一个好主意,即使它工作得非常好: def insert(list: List[Any], i: Int, value: Any) = { list.take(i) ++ List(value) ++ list.drop(i) } 用法: scala> insert(List(1,2,3,5), 3, 4) res62: List[Any] = List(1, 2, 3,

列表中没有内置函数或方法允许用户在列表的某个位置添加新元素。我已经编写了一个函数来实现这一点,但我不确定这样做是否是一个好主意,即使它工作得非常好:

def insert(list: List[Any], i: Int, value: Any) = {
  list.take(i) ++ List(value) ++ list.drop(i)
}
用法:

scala> insert(List(1,2,3,5), 3, 4)
res62: List[Any] = List(1, 2, 3, 4, 5)
类型安全 我看到的最明显的事情是缺乏类型安全性/类型信息丢失。我将使该方法在列表的元素类型中通用:

def insert[T](list: List[T], i: Int, value: T) = {
  list.take(i) ++ List(value) ++ list.drop(i)
}
风格 如果主体仅由单个表达式组成,则不需要大括号:

def insert[T](list: List[T], i: Int, value: T) = 
  list.take(i) ++ List(value) ++ list.drop(i)
效率 关于使用避免遍历列表两次的注释也是一个很好的注释:

def insert[T](list: List[T], i: Int, value: T) = {
  val (front, back) = list.splitAt(i)
  front ++ List(value) ++ back
}
接口 一次插入多个值可能比较方便:

def insert[T](list: List[T], i: Int, values: T*) = {
  val (front, back) = list.splitAt(i)
  front ++ values ++ back
}
接口,取2 您可以将其作为
列表的扩展方法

implicit class ListWithInsert[T](val list: List[T]) extends AnyVal {
  def insert(i: Int, values: T*) = {
    val (front, back) = list.splitAt(i)
    front ++ values ++ back
  }
}

List(1, 2, 3, 6).insert(3, 4, 5)
// => List(1, 2, 3, 4, 5, 6)
闭幕词
但是,请注意,插入到列表中间并不适合cons列表。你最好使用一个(可变的)链表或动态数组。

你也可以使用
xs.patch(i,ys,r)
,它用补丁
ys
替换
xs
r
元素,使用
r=0
,并使
ys
成为一个单件:

List(1, 2, 3, 5).patch(3, List(4), 0)


最多遍历一次。

不是答案,但我建议使用
.splitAt
而不是
。使用
删除
(以避免在列表中重复两次)。这可能更合适。我将以该网站的精神回答:“没有内置函数或列表方法允许用户添加新元素”,但有这样一种方法-它被称为
patch
。回答得很好。小挑剔:你可以用
front++values++back
替换
front++List(值:*)++back
。是的,谢谢。我太专注于保持原始版本。有点离题:为什么
ListWithInsert
扩展AnyVal
?@dmitry:为什么不?毕竟,enrich my library是一开始引入值类的主要动机之一。谢谢,我还没有意识到这样的代码评审服务是存在的。在不久的将来,我肯定会用更多的scala示例来使用它
def insert(list: List[Any], i: Int, value: Any): List[Any] = list match {
  case head :: tail if i > 0 => head :: insert(tail, i-1, value)
  case _ => value :: list
}