it-swarm.com.de

Wie entferne ich ein Element aus einer Liste in Scala, die nur den Index enthält?

Ich habe eine Liste wie folgt:

val internalIdList: List[Int] = List()

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

Aus dieser Liste entfernen Sie das dritte Element, um Folgendes zu erhalten:

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

Ich kann keine ListBuffer verwenden, bin verpflichtet die vorhandene Struktur beizubehalten. Wie kann ich?

Dank an alle

14
YoBre

Wenn Sie wissen, dass Sie das dritte Element (Index 2) löschen werden, können Sie es einfach verwenden

val trunced = internalIdList.take(2) ++ internalIdList.drop(3)

wenn Sie vorher nicht wissen, wie der Index des zu entfernenden Elements aussieht, können Sie eine Funktion wie die folgende schreiben:

def removeIndex(ix: Int) = if (internalIdList.size < ix) internalIdList
                           else internalIdList.take(ix) ++ internalIdList.drop(ix+1)
13
Shadowlands

Es gibt eine .patch-Methode für Seq. Um das dritte Element zu entfernen, können Sie dies einfach tun:

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

Was sagt: Ab Index 2 , entfernen Sie bitte 1 element und ersetzen Sie es durch Null .

Wenn Sie diese Methode eingehend kennen, können Sie noch viel mehr tun. Sie können jede Unterliste einer Liste mit einer beliebigen anderen Liste austauschen.

38
Rok Kralj

Eine idiomatische Methode besteht darin, den Wert mit seinem Index zu komprimieren, zu filtern und den Wert erneut zu projizieren:

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

Sie können jedoch auch splitAt verwenden:

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)
10
Nicolas

Wenn Sie auf der Oldschool-Methode bestehen, verwenden Sie collect:

List(1,2,3,4).zipWithIndex.collect { case (a, i) if i != 2 => a }

In meiner anderen Antwort ziehe ich jedoch immer noch die Methode vor.

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

Um dies zu verallgemeinern ...

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

Obwohl dies oft einen Vektor zurückgibt, müssten Sie dies tun

val otherList = removeIndex(internalIdList, 3).toList

Wenn Sie wirklich eine Liste haben wollten.

Shadowlands hat eine Lösung, die tendenziell für lineare Sequenzen schneller ist. Dieser wird mit indizierten Sequenzen schneller sein.

1
itsbruce

Eine generische Funktion, die die erste Lösung von Nicolas implementiert:

def dropIndex[T](list: List[T], idx: Int): List[T] =
  list.zipWithIndex.filter(_._2 != idx).map(_._1)

Verwendungszweck:

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)
0
simleo

Mit einem Verständnis für eine Liste xs wie folgt,

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

Berücksichtigen Sie auch eine Reihe von Ausschlussindizes, zum Beispiel val excl = Set(2,4), um die zweite und vierte Position auszuschließen. Daher sammeln wir diejenigen Artikel, deren Indizes nicht zum Ausschlusssatz gehören, nämlich 

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