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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31037384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:18:18  来源:igfitidea点击:

Insert a new element in a specified position of a list

scala

提问by HeeL

There is no built-in function or a method of a List that would allow user to add a new element in a certain position of a List. I've wrote a function that does this but I'm not sure that its a good idea to do it this way, even though it works perfectly well:

没有内置函数或 List 方法可以允许用户在 List 的某个位置添加新元素。我已经编写了一个执行此操作的函数,但我不确定以这种方式执行此操作是否是一个好主意,即使它运行得非常好:

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

Usage:

用法:

scala> insert(List(1,2,3,5), 3, 4)
res62: List[Any] = List(1, 2, 3, 4, 5)

回答by J?rg W Mittag

Type Safety

类型安全

The most glaring thing I see is the lack of type safety / loss of type information. I would make the method generic in the list's element type:

我看到的最明显的事情是缺乏类型安全/类型信息丢失。我会在列表的元素类型中使该方法通用:

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

Style

风格

If the body only consists of a single expression, there is no need for curly braces:

如果主体只包含一个表达式,则不需要花括号:

def insert[T](list: List[T], i: Int, value: T) = 
  list.take(i) ++ List(value) ++ list.drop(i)

Efficiency

效率

@Marth's comment about using List.splitAtto avoid traversing the list twice is also a good one:

@Marth关于使用List.splitAt避免两次遍历列表的评论也是一个很好的评论:

def insert[T](list: List[T], i: Int, value: T) = {
  val (front, back) = list.splitAt(i)
  front ++ List(value) ++ back
}

Interface

界面

It would probably be convenient to be able to insert more than one value at a time:

能够一次插入多个值可能会很方便:

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

Interface, take 2

接口,取2

You could make this an extension method of List:

您可以将其设为以下扩展方法List

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)

Closing remarks

结束语

Note, however, that inserting into the middle of the list is just not a good fit for a cons list. You'd be much better off with a (mutable) linked list or a dynamic array instead.

但是请注意,插入列表中间并不适合 cons 列表。使用(可变)链表或动态数组会更好。

回答by Ben Reich

You can also use xs.patch(i, ys, r), which replaces relements of xsstarting with iby the patch ys, by using r=0and by making ysa singleton:

您还可以使用xs.patch(i, ys, r),它通过使用和制作单例来替换补丁开头的r元素:xsiysr=0ys

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

回答by serv-inc

In the Scala course by his eminence Martin Odersky himself, he implements it similarly to

他的卓越 Martin Odersky 本人的 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
}

One traversal at most.

最多一次遍历。