dartlistmapwhereMenengah4 mnt baca

Transformasi List: map & where

Mengubah dan memfilter list secara deklaratif dengan map, where, expand.

Dari loop manual ke gaya deklaratif

Untuk menggandakan tiap elemen list, cara lama butuh loop + list kosong + add. map dan where menggantikannya dengan satu baris yang mendeklarasikan hasil yang diinginkan, bukan langkahnya.

Analogi: loop manual itu seperti memberi tahu asisten langkah demi langkah ("ambil yang pertama, kali dua, taruh di kotak..."). map/where itu seperti berkata "kalikan semua dengan dua", asisten yang mengurus caranya.

Kenapa gaya deklaratif menang?

Tiga alasan: lebih ringkas (1 baris vs 5), lebih jelas (niat terlihat langsung), dan lebih aman (tidak ada index, tidak ada off-by-one). Di Flutter, 90% pengolahan list memakai gaya ini.

map: ubah tiap elemen

dart
void main() {
  var angka = [1, 2, 3, 4];

  // Cara lama
  var hasil1 = <int>[];
  for (var n in angka) {
    hasil1.add(n * 2);
  }

  // Cara map: satu baris
  var hasil2 = angka.map((n) => n * 2).toList();

  print(hasil1); // [2, 4, 6, 8]
  print(hasil2); // [2, 4, 6, 8]
}

map menerapkan fungsi ke tiap elemen dan mengumpulkan hasilnya. Jangan lupa .toList(): map mengembalikan Iterable malas.

Contoh kedua, map mengubah tipe:

dart
class Siswa {
  String nama;
  int nilai;
  Siswa(this.nama, this.nilai);
}

void main() {
  var siswa = [Siswa('Budi', 85), Siswa('Ani', 92)];

  // List<Siswa> -> List<String>
  var nama = siswa.map((s) => s.nama).toList();
  print(nama); // [Budi, Ani]

  // List<Siswa> -> List<String> yang diformat
  var laporan = siswa.map((s) => '${s.nama}: ${s.nilai}').toList();
  print(laporan); // [Budi: 85, Ani: 92]
}

Di Flutter, pola ini dipakai terus: listSiswa.map((s) => Text(s.nama)).toList() mengubah data menjadi widget.

where: saring elemen

dart
void main() {
  var nilai = [55, 80, 45, 90, 70];

  var lulus = nilai.where((n) => n >= 70).toList();
  print(lulus); // [80, 90, 70]

  // Rantai: saring lalu ubah
  var pesan = nilai
      .where((n) => n < 70)
      .map((n) => 'Remedial: $n')
      .toList();
  print(pesan); // [Remedial: 55, Remedial: 45]
}

where mempertahankan elemen yang memenuhi syarat. Rantai where→map adalah pola harian: saring dulu, ubah kemudian.

expand: ratakan list bersarang

dart
void main() {
  var grup = [
    [1, 2],
    [3, 4],
    [5]
  ];

  var rata = grup.expand((g) => g).toList();
  print(rata); // [1, 2, 3, 4, 5]

  // Tiap elemen jadi BANYAK elemen
  var kata = ['hi', 'yo'];
  print(kata.expand((k) => k.split('')).toList()); // [h, i, y, o]
}

expand memetakan tiap elemen menjadi iterable, lalu meratakannya. Lawan dari map yang 1-ke-1, expand itu 1-ke-banyak.

Kesalahan umum

1. Lupa toList()

dart
void main() {
  var angka = [1, 2, 3];
  var hasil = angka.map((n) => n * 2);
  print(hasil); // (2, 4, 6) <- Iterable, bukan List!
  // hasil.add(10); // ERROR
  var listHasil = hasil.toList();
  listHasil.add(10);
  print(listHasil); // [2, 4, 6, 10]
}

2. Mengira map mengubah list asli

dart
void main() {
  var angka = [1, 2, 3];
  angka.map((n) => n * 2); // hasil dibuang!
  print(angka); // [1, 2, 3], tidak berubah
}

map/where tidak mengubah asli; mereka menghasilkan koleksi baru. Simpan hasilnya!

3. where dengan efek samping

dart
// BURUK: where untuk aksi, bukan filter
void main() {
  var angka = [1, 2, 3];
  // angka.where((n) { print(n); return true; }).toList();
}

Butuh aksi per elemen? Pakai forEach atau for-in. where hanya untuk memfilter.

Kesimpulan

map = ubah tiap elemen (1-ke-1), where = saring, expand = ratakan (1-ke-banyak). Selalu akhiri dengan .toList() jika butuh List. Gaya deklaratif ini adalah bahasa sehari-hari Dart modern dan Flutter.

Catatan teknis: Rantai map/where bersifat lazy: tidak ada komputasi sampai diiterasi. Untuk list besar, ini hemat memori dibanding membuat list perantara di tiap tahap.

Tantangan

Laporan nilai

Dari list nilai [55, 80, 45, 90, 70], buat list string laporan HANYA untuk yang lulus (>= 70) dengan format 'Nilai 80: LULUS'. Pakai where + map + toList.

text
void main() {
  var nilai = [55, 80, 45, 90, 70];
  // TODO: where + map + toList
}