他の人とは異なり、インデックスの再番号付けに関する懸念に言及しているため、その場で作業を行いたいと考えています。並べ替えだけが重要な場合
1) 削除するインデックスを、リストではなく一定時間のルックアップ セットに貼り付けます。インデックスの範囲によっては、ハッシュ セットまたはビット セットが適切と思われます。2) 削除するセットにあるインデックスを削除しながら、逆の順序でリスト バッファーをウォークします。
scala> val buffer = ListBuffer("a", "b", "c", "d", "e")
buffer: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, b, c, d, e)
scala> val indicesToDelete = BitSet(4, 1)
indicesToDelete: scala.collection.mutable.BitSet = BitSet(1, 4)
scala> for (i <- (buffer.size -1) to 0 by -1) if (indicesToDelete contains i) buffer remove i
scala> buffer
res19: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, c, d)
これにより n log n ソートのインデックスが削除されますが、これは線形アルゴリズムにはなりません。配列のような構造からのインプレース削除は安価ではありません。削除するたびに、より高いインデックスを下方にコピーする必要があります。
インデックスの線形削除を取得するには、もっと面倒なことをする必要があります。1) これまでに削除した数に基づいて、削除されていない要素を下にコピーして、順方向に歩く必要があります。完了したら、2) 上位 n 個の要素を削除します。ここで、n は削除した番号です。
scala> val buffer = ListBuffer("a", "b", "c", "d", "e")
buffer: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, b, c, d, e)
scala> val indicesToDelete = BitSet(4, 1)
indicesToDelete: scala.collection.mutable.BitSet = BitSet(1, 4)
scala> var deleted = 0
deleted: Int = 0
scala> for (i <- 0 until buffer.size)
| if (indicesToDelete contains i) {
| deleted += 1
| } else if (deleted > 0) {
| buffer(i - deleted) = buffer(i)
| }
scala> }
scala> buffer trimEnd deleted
scala> buffer
res0: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, c, d)