2

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
  • 7,910
  • 6
  • 49
  • 67

2 Answers2

8

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

array.subList(2, 4).clear();
Shermano
  • 1,030
  • 8
  • 28
2

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,153
  • 24
  • 25