如何在Scala中通过索引从列表中删除一个项目?

25

我有一个如下的列表:

val internalIdList: List[Int] = List()

internalIdList = List(11, 12, 13, 14, 15)

从这个列表中删除第三个元素,就能得到:

internalIdList = List(11, 12, 14, 15)

我不能使用ListBuffer,必须保持现有的结构。 我该怎么办?

谢谢大家

7个回答

58

Seq 上有一个 .patch 方法,所以要删除第三个元素,你可以简单地这样做:

只需使用 .patch 方法即可。

List(11, 12, 13, 14, 15).patch(2, Nil, 1)

内容:从索引2开始,请删除1个元素,并将其替换为Nil

深入了解这种方法可以让您做更多的事情。您可以将列表的任何子列表与其他任意列表进行交换。


3
我喜欢它!而且,实际上我确实想要“修补”这个列表,而不仅仅是从中删除一个元素。所以我本来在寻找错误问题的答案,但还是感谢你让我找到了解决办法。 - Peter Perháč

22

只需使用

val trunced = internalIdList.take(index) ++ internalIdList.drop(index + 1)

如果索引大于列表的大小,这也将起作用(它将返回相同的列表)。


3
如果给定的索引大于列表长度, if/else 语句是无用的:使用 take 和 drop 函数会按预期行事。 - Nicolas

13

一种惯用的方法是将值与它们的索引进行zip操作,然后进行过滤,最后再次投影出值:

scala> List(11,12,13,14,15).zipWithIndex.filter(_._2 != 2).map(_._1)
res0: List[Int] = List(11, 12, 14, 15)

但你也可以使用splitAt

scala> val (x,y) = List(11,12,13,14,15).splitAt(2)
x: List[Int] = List(11, 12)
y: List[Int] = List(13, 14, 15)

scala> x ++ y.tail
res5: List[Int] = List(11, 12, 14, 15)

5
如果您坚持使用老旧的方法,请使用 collect:
List(1,2,3,4).zipWithIndex.collect { case (a, i) if i != 2 => a }

然而,我仍更喜欢我其他答案中的方法。

1
这太棒了! - Kevin eyeson
很高兴你喜欢它,不过我建议使用我的.patch()答案。;) - Rok Kralj

2
一个通用函数,实现了Nicolas的第一个解决方案:
def dropIndex[T](list: List[T], idx: Int): List[T] =
  list.zipWithIndex.filter(_._2 != idx).map(_._1)

使用方法:

scala> val letters = List('a', 'b', 'c')
scala> for (i <- 0 until letters.length) println(dropIndex(letters, i))
List(b, c)
List(a, c)
List(a, b)

1
(internalIdList.indices.collect { case i if i != 3 => internalList(i) }).toList

将此通用化...
def removeIndex[A](s: Seq[A], n: Int): Seq[A] = s.indices.collect { case i if i != n => s(i) }

虽然这通常会返回一个向量,因此您需要执行
val otherList = removeIndex(internalIdList, 3).toList

如果你真的想要一个列表回来。
影之国有一个解决方案,对于线性序列来说,它通常会更快。而这个解决方案则在索引序列中更快。

0

在列表xs上使用for推导式,像这样:

for (i <- 0 until xs.size if i != nth-1) yield xs(i)

同时考虑一组排除索引,例如val excl = Set(2,4)用于排除第二和第四个项目; 因此我们收集那些索引不属于排除集合的项目,即

for (i <- 0 until xs.size if !excl(i)) yield xs(i)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接