Swap Function in Kotlin

Kotlin

Kotlin Problem Overview


is there any better way to write generic swap function in kotlin other than java way described in https://stackoverflow.com/questions/3624525/how-to-write-a-basic-swap-function-in-java.

Is there any kotlin language feature which can make generic swap function more concise and intuitive?

Kotlin Solutions


Solution 1 - Kotlin

No need a swap function in Kotlin at all. you can use the existing also function, for example:

var a = 1
var b = 2

a = b.also { b = a }

println(a) // print 2
println(b) // print 1

Solution 2 - Kotlin

If you want to write some really scary code, you could have a function like this:

inline operator fun <T> T.invoke(dummy: () -> Unit): T {
    dummy()
    return this
}

That would allow you to write code like this

a = b { b = a }

Note that I do NOT recommend this. Just showing it's possible.

Solution 3 - Kotlin

Edit: Thanks to @hotkey for his comment

I believe the code for swapping two variables is simple enough - not to try simplifying it any further.

The most elegant form of implementation IMHO is:

var a = 1
var b = 2

run { val temp = a; a = b; b = temp }

println(a) // print 2
println(b) // print 1

Benefits:

  • The intent is loud and clear. nobody would misunderstand this.
  • temp will not remain in the scope.

Solution 4 - Kotlin

Kotlin encourages the use of immutable data when possible (such as using val instead of var). This greatly reduces the change for subtle bugs, since it's possible to reason more soundly about code if values don't change.

Swapping two values is very much the opposite of immutable data: Did I mean the value of a before or after the swap?

Consider rewriting your code in the following immutable way:

val a = 1
val b = 2

val (a2, b2) = b to a

This works by making use of destructuring declarations, along with the built-in to extension function that creates a Pair.

Solution 5 - Kotlin

That is a good usage for with:

var a = 1
var b = 2

with(a) {
    a = b
    b = this
}

println(a) // 2
println(b) // 1

Solution 6 - Kotlin

Very simple, fast and elegant solution:

var a = 1
var b = 2
val (b0, a0) = a swap b
a = a0
b = b0

infix fun <A> A.swap(second: A): Pair<A, A> = second to this

Solution 7 - Kotlin

prefer a=b.apply {b=a} for swapping the elements. If we want to perform some operation on the variable inside the lambda, then go for a = b.also {someFun(it)}

Solution 8 - Kotlin

If you're swapping array values in place, from a code readability perspective, it was helpful for me to add an extension function swapInPlace

fun <T> Array<T>.swapInPlace(i1: Int, i2: Int){
  this[i1] = this[i2].also{ this[i2] = this[i1] }
}

fun main(){
 val numbers = arrayOf(2, 1)

 //This is easier for me to read...
 numbers.swapInPlace(0, 1)

 //Compared to this
 numbers[0] = numbers[1].also{ numbers[1] = numbers[0] }
}

Solution 9 - Kotlin

I have something interesting for all: > Why just numbers. We can swap anything with a generic class and a generic function

class Mutable<T>(var value: T) {
    override fun toString() = value.toString()

    /**
    infix fun swapWith(other: Mutable<T>) {
        value = other.value.also { other.value = value }
	}
    **/
}

fun <T> swap(num1: Mutable<T>, num2: Mutable<T>) {
    num1.value = num2.value.also { num2.value = num1.value }
}

fun main() {
    val num1 = Mutable(4)
    val num2 = Mutable(6)

    println("Before Swapping:-\n\tNumber#1 is: $num1\n\tNumber#2 is: $num2\n")

    //calling way of class method is not like usual swap function
    //num1 swapWith num2

    //calling the actual swap function.
    swap(num1, num2)

    println("After Swapping:-\n\tNumber#1 is: $num1\n\tNumber#2 is: $num2\n")
}
  • class Mutable is a generic class here which can contain any type of data into it. > I overridden toString() method to directly accessing the value attribute by just calling the object.

  • fun swap is a true swap function for kotlin that gives you the call by reference's demo too.

  • operator swapWith also works as swap function, which is a part of Mutable class. I have commented that part because the calling way for the operator is not like the way we are used to with.

Output:

Before Swapping:-
	Number#1 is: 4
	Number#2 is: 6

After Swapping:-
	Number#1 is: 6
	Number#2 is: 4

Solution 10 - Kotlin

In order to use Kotlin List you could create this kind of extension. It returns a copy of this list with elements at indices a and b swapped.

fun <T> List<T>.swap(a: Int, b: Int): List<T> = this
    .toMutableList()
    .also {
        it[a] = this[b]
        it[b] = this[a]
    }

Solution 11 - Kotlin

If you use an array, you can use this:

fun <T> Array<T>.swap(i: Int, j: Int) {
    with(this[i]) {
        this@swap[i] = this@swap[j]
        this@swap[j] = this
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAkshar PatelView Question on Stackoverflow
Solution 1 - Kotlinholi-javaView Answer on Stackoverflow
Solution 2 - KotlinRuckus T-BoomView Answer on Stackoverflow
Solution 3 - KotlinLior Bar-OnView Answer on Stackoverflow
Solution 4 - KotlingavrieView Answer on Stackoverflow
Solution 5 - KotlinWilli MentzelView Answer on Stackoverflow
Solution 6 - KotlinrepitchView Answer on Stackoverflow
Solution 7 - KotlinVinodh ThimmisettyView Answer on Stackoverflow
Solution 8 - KotlinJonathan WardView Answer on Stackoverflow
Solution 9 - KotlinEr. Harsh RathoreView Answer on Stackoverflow
Solution 10 - KotlinNicolas DuponchelView Answer on Stackoverflow
Solution 11 - Kotlinandroid developerView Answer on Stackoverflow