Loop bersarang (nested loop) adalah loop yang berada di dalam loop lain. Konstruksi ini muncul pada banyak algoritma: traversal matriks 2D, pembuatan pola geometri, kombinasi pasangan elemen, dan algoritma sorting sederhana. Kotlin mendukung nested loop pada semua konstruksi (for, while, do-while) dengan sintaks yang alami. Pada chapter ini kita akan membangun tabel perkalian, traversal matriks, pola segitiga bintang, serta membahas variable shadowing dan pertimbangan performa.

Pola Dasar Nested Loop #

Setiap iterasi loop luar memicu seluruh iterasi loop dalam. Bila loop luar berjalan M kali dan loop dalam N kali, total iterasi body dalam adalah M × N.

kotlin
fun main() {
    // Nested for: tabel perkalian
    println("Tabel perkalian 1..5:")
    print("   ")
    for (j in 1..5) print("%3d".format(j))
    println()
    for (i in 1..5) {
        print("%2d: ".format(i))
        for (j in 1..5) {
            print("%3d".format(i * j))
        }
        println()
    }

    // Traversal matriks 2D
    val matriks = arrayOf(
        intArrayOf(1, 2, 3),
        intArrayOf(4, 5, 6),
        intArrayOf(7, 8, 9)
    )
    println("Isi matriks:")
    for (baris in matriks) {
        for (nilai in baris) {
            print("$nilai ")
        }
        println()
    }

    // Hitung total seluruh elemen
    var total = 0
    for (i in matriks.indices) {
        for (j in matriks[i].indices) {
            total += matriks[i][j]
        }
    }
    println("Total seluruh elemen: $total")

    // Variable shadowing: inner i menutupi outer i
    println("Variable shadowing pada inner loop:")
    for (i in 1..3) {
        for (i in 10..11) {
            print("inner-i=$i ")
        }
        println("outer-i=$i")
    }

    // Pola segitiga bintang
    println("Pola segitiga:")
    val tinggi = 4
    for (baris in 1..tinggi) {
        for (spasi in 1..(tinggi - baris)) {
            print(" ")
        }
        for (bintang in 1..(2 * baris - 1)) {
            print("*")
        }
        println()
    }
}

Output yang Dihasilkan:

text
Tabel perkalian 1..5:
     1  2  3  4  5
 1:   1  2  3  4  5
 2:   2  4  6  8 10
 3:   3  6  9 12 15
 4:   4  8 12 16 20
 5:   5 10 15 20 25
Isi matriks:
1 2 3 
4 5 6 
7 8 9 
Total seluruh elemen: 45
Variable shadowing pada inner loop:
inner-i=10 inner-i=11 outer-i=1
inner-i=10 inner-i=11 outer-i=2
inner-i=10 inner-i=11 outer-i=3
Pola segitiga:
   *
  ***
 *****
*******

Mari kita bedah setiap bagian penting:

  1. Tabel perkalian: loop luar i (1..5) mengiterasi baris, loop dalam j (1..5) mengiterasi kolom. Setiap sel berisi i * j. Fungsi "%3d".format(...) mencetak angka dengan lebar 3 karakter agar kolom rapi.
  2. Traversal matriks 2D: arrayOf(intArrayOf(...)) membentuk array 2D. Loop luar mengiterasi baris (tiap IntArray), loop dalam mengiterasi nilai di dalam baris tersebut. Pendekatan ini lebih ringkas daripada mengakses matriks[i][j] lewat indeks.
  3. Penjumlahan dengan indeks: ketika kita butuh posisi [i][j], gunakan matriks.indices dan matriks[i].indices. Variabel total diakumulasi dari setiap elemen.
  4. Variable shadowing: loop dalam mendeklarasikan i yang menutupi i loop luar. Di dalam loop dalam, i merujuk ke inner-i (10, 11). Setelah loop dalam selesai, i kembali merujuk ke outer-i (1, 2, 3). Praktik ini legal namun membingungkan.
  5. Pola segitiga bintang: tiga loop bersarang. Loop luar mengiterasi baris; loop pertama di dalam mencetak spasi; loop kedua mencetak bintang. Jumlah spasi tinggi - baris dan jumlah bintang 2 * baris - 1 membentuk segitiga sama kaki.

Traversal Matriks #

Matriks 2D sering direpresentasikan sebagai Array<IntArray>. Dua cara umum mengiterasinya:

  • Elemen langsung: for (baris in matriks) for (nilai in baris) — lebih bersih.
  • Indeks: for (i in matriks.indices) for (j in matriks[i].indices) — perlu saat ingin tahu posisi.

Variable Shadowing #

Variable shadowing terjadi ketika variabel di scope dalam memiliki nama yang sama dengan variabel di scope luar, sehingga variabel luar tidak terlihat dari dalam. Kotlin memperbolehkan ini, tetapi praktik terbaik adalah menghindari shadowing untuk mengurangi kebingungan.

Pertimbangan Performa #

Kompleksitas nested loop adalah O(M × N). Untuk matriks kecil, ini bukan masalah. Namun pada dataset besar (mis. matriks 1000×1000), satu juta iterasi dapat memengaruhi waktu eksekusi.

Pola Umum Nested Loop #

PolaPenerapan
Traversal matriksfor (baris in matriks) for (nilai in baris)
Kombinasi pasanganfor (i in list.indices) for (j in i+1 until list.size)
Pola geometriloop luar baris, loop dalam cetak karakter
Tabel dataloop luar kolom header, loop dalam cetak sel

Referensi Lanjutan #

Setelah memahami nested loop, chapter terakhir section ini akan membahas bagaimana kompilator Kotlin menganalisis alur kontrol untuk mengaktifkan fitur smart cast pada if, when, dan kombinasi kondisi.