Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

scala - Insert a new element in a specified position of a list

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:

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)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.splitAt to avoid traversing the list twice is also a good one:

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

You could make this an extension method of 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...