3

Is there any function in Kotlin to remove a specific range of elements as in Java.

In Java we have a method called removeRange which can be extended and can be made useful.

expect class ArrayList<E> :MutableList<E>,RandomAccess{
    constructor()
    constructor(initialCapacity:Int)
    constructor(elements:Collection<E>)

    fun trimToSize()
    fun ensureCapacity(minCapacity:Int)

   // From List

    override val size:Int
    override fun isEmpty():Boolean
    override fun contains(element:@UnsafeVariance E):Boolean
    override fun containsAll(elements:Collection<@UnsafeVariance E>):Boolean
    override operator fun get(index:Int):E
    override fun indexOf(element:@UnsafeVariance E):Int
    override fun lastIndexOf(element:@UnsafeVariance E):Int

   // From MutableCollection

    override fun iterator():MutableIterator<E>

   // From MutableList

    override fun add(element:E):Boolean
    override fun remove(element:E):Boolean
    override fun addAll(elements:Collection<E>):Boolean
    override fun addAll(index:Int,elements:Collection<E>):Boolean
    override fun removeAll(elements:Collection<E>):Boolean
    override fun retainAll(elements:Collection<E>):Boolean
    override fun clear()
    override operator fun set(index:Int,element:E):E
    override fun add(index:Int,element:E)
    override fun removeAt(index:Int):E
    override fun listIterator():MutableListIterator<E>
    override fun listIterator(index:Int):MutableListIterator<E>
    override fun subList(fromIndex:Int,toIndex:Int):MutableList<E>
    }

removeRange was added in 1.1 of Kotlin but was removed in 1.3

Manoj Perumarath
  • 9,337
  • 8
  • 56
  • 77

3 Answers3

13

removeRange is protected in kotlin, but this should do the trick:

array.subList(2, 4).clear();
Shermano
  • 1,100
  • 8
  • 31
  • cool, save my day man! – Amos Aug 14 '22 at 04:15
  • It's working, but in my case, I need to delete the first n number(like first 3) of index values. val list = mutableListOf(0, 1, 2, 3, 4,5.6.7.8,9,10) list.subList(1..3).clear() print(list) – RaJ Feb 09 '23 at 13:17
3

There is no clean way to do that. Shermano is right. It's no nice, but it is the best way. Your options

a) Use dropLast or drop

However, you cannot use type casting for ArrayList

lis = lis.dropLast(1) as ArrayList<Int>  

It gives a runtime error. One has to declare the variable like MutableList, that is almost the same.

   var lis = mutableListOf(2,3,4)
   lis = lis.dropLast(2) as MutableList<Int>
   println("dropLast: ${lis.size} ${lis[0]}")

It prints

dropLast: 1 2

You also can use lis.dropLast(2).toMutableList()

b) Use for statement

var lis=arrayListOf(2,3,4)   
for (i in lis.indices.reversed()) {
   if (i>=1 && i<=2) lis.removeAt(i)
}
println("for: ${lis.size} ${lis[0]}")

Notice that one needs to delete backwards.

It prints

for: 1 2

c) Use subList

   var lis = arrayListOf(2,3,4)
   lis.subList(1,3).clear()
   println("subList: ${lis.size} ${lis[0]}")

It prints

subList: 1 2

/*/

I prefer the third option encapsulated in some inline function.

inline fun <T> ArrayList<T>.delLen(ini:Int, len:Int=-1) {
  if (len == -1)
    this.subList(ini,this.size).clear()
  else
    this.subList(ini,ini+len).clear()
}

So

lis.delLen(0,2) // delete the 0th postion for 2 positions.
lis.dellen(1)  // delete from 1st postion forward. 

I also like

inline fun <T> ArrayList<T>.delLast(n:Int=1) {
  this.subList(this.size-n,this.size).clear()
}

Examples

lis.delLast() // delete the last position
list.delLast(3) // delete last 3 positions
Paulo Buchsbaum
  • 2,471
  • 26
  • 29
1

I was also looking for this. Since there seems to be no method for this, you can create one using extension functions:

val IntRange.end: Int get() =
    last + 1

fun <T> MutableList<T>.subList(range: IntRange) =
    subList(range.first, range.end)

fun <T> MutableList<T>.removeRange(range: IntRange) =
    subList(range).clear()

Example usage:

val list = mutableListOf<Int>(0, 1, 2, 3, 4)
list.removeRange(2 until 4)
print(list)  // Outputs [0, 1, 4]
user42723
  • 467
  • 3
  • 8