Masukkan Password
42 4.4 Where in Dart Programming Language | Filter List Map Set | Learn Dart Language | Dart Course
Materi kali ini membahas filtering/pencarian data menggunakan where() di Dart. Ini materi yang penting karena where() sering sekali dipakai ketika kita bekerja dengan List, Set, dan Map.
Saya akan jelaskan dari dasar dulu, lalu satu per satu fungsi yang ada di caption.
1. Apa itu where()?
Secara sederhana, where() berarti:
“Ambil hanya data yang memenuhi kondisi tertentu.”
Atau dalam bahasa sehari-hari:
Filter data.
Misalnya kita punya daftar nama:
List<String> names = [
"Alice",
"Bob",
"Charlie",
"Henry",
"Ivy",
];
Kita ingin mengambil nama yang dimulai dengan huruf A.
Tanpa where(), kita harus membuat loop:
for (var name in names) {
if (name.startsWith("A")) {
print(name);
}
}
Dengan where():
var result = names.where((name) {
return name.startsWith("A");
}).toList();
Hasil:
[Alice]
Jadi where() sangat berguna untuk menyaring data.
2. Cara kerja where()
Bentuk umumnya:
collection.where((element) {
return condition;
});
Misalnya:
names.where((name) {
return name.startsWith("A");
});
Kita bisa membacanya:
“Dari semua
namedi dalamnames, ambil yangname-nya diawali huruf A.”
Apa itu element?
Pada:
(name) {
return name.startsWith("A");
}
name mewakili satu elemen yang sedang diperiksa.
Misalnya list:
Alice
Bob
Charlie
Henry
Ivy
Maka where() akan memeriksa satu per satu:
Alice → startsWith("A") → true → ambil
Bob → startsWith("A") → false → buang
Charlie → startsWith("A") → false → buang
Henry → startsWith("A") → false → buang
Ivy → startsWith("A") → false → buang
Hasil:
Alice
3. Arrow Function
Di caption banyak digunakan bentuk:
(name) => name.startsWith("A")
Ini disebut arrow function.
Bentuk lengkap:
(name) {
return name.startsWith("A");
}
Bisa dipersingkat menjadi:
(name) => name.startsWith("A");
Artinya sama.
Jadi:
names.where((name) {
return name.startsWith("A");
});
sama dengan:
names.where((name) => name.startsWith("A"));
Untuk kondisi sederhana, arrow function biasanya lebih ringkas.
4. Kenapa hasil where() disebut Iterable?
Ini salah satu bagian yang sering membingungkan pemula.
Ketika kita menulis:
var result = names.where((name) => name.startsWith("A"));
hasilnya bukan langsung List<String>, tetapi:
Iterable<String>
Kalau kita membutuhkan List, kita bisa menggunakan:
.toList()
Jadi:
List<String> result =
names.where((name) => name.startsWith("A")).toList();
Polanya:
List
↓
where()
↓
Iterable
↓
toList()
↓
List
Ini penting untuk diingat.
5. Contoh where() berdasarkan huruf awal
Misalnya:
List<String> names = [
"Alice",
"Bob",
"Charlie",
"Henry",
"Ivy",
];
Mencari nama yang dimulai dengan A:
var result = names
.where((name) => name.startsWith("A"))
.toList();
print(result);
Hasil:
[Alice]
Kalau:
name.startsWith("B")
hasil:
[Bob]
6. startsWith()
name.startsWith("A")
artinya:
Apakah string ini dimulai dengan
"A"?
Contoh:
"Alice".startsWith("A") // true
"Bob".startsWith("A") // false
7. endsWith()
Kebalikannya adalah:
name.endsWith("y")
Artinya:
Apakah string ini diakhiri dengan
"y"?
Contoh:
"Alice".endsWith("y") // false
"Henry".endsWith("y") // true
"Ivy".endsWith("y") // true
Jadi:
var result = names
.where((name) => name.endsWith("y"))
.toList();
akan mengambil semua nama yang berakhiran y.
8. contains()
Kalau kita ingin mencari apakah sebuah teks mengandung karakter tertentu, gunakan:
contains()
Contoh:
var result = names
.where((name) => name.contains("a"))
.toList();
Artinya:
Ambil nama yang mengandung huruf
a.
Perlu diperhatikan, pencarian String bersifat case-sensitive.
Misalnya:
"Alice".contains("A") // true
"Alice".contains("a") // false
Karena A dan a berbeda.
Kalau ingin tidak peduli huruf besar/kecil:
var result = names
.where((name) => name.toLowerCase().contains("a"))
.toList();
9. Filter berdasarkan length
Kita juga tidak harus menggunakan String.
Misalnya:
var result = names
.where((name) => name.length > 4)
.toList();
Artinya:
Ambil nama yang panjangnya lebih dari 4 karakter.
Contoh:
Alice → 5 → masuk
Bob → 3 → tidak
Charlie → 7 → masuk
Henry → 5 → masuk
Ivy → 3 → tidak
Hasil:
[Alice, Charlie, Henry]
10. firstWhere()
Sekarang kita masuk ke fungsi yang berbeda.
where():
Mengambil semua data yang cocok.
Sedangkan:
firstWhere()
Mengambil data pertama yang cocok.
Misalnya:
var result = names.firstWhere(
(name) => name.endsWith("y"),
);
Misalkan:
Alice
Bob
Charlie
Henry
Ivy
Yang berakhiran y:
Charlie
Henry
Ivy
Tetapi firstWhere() hanya mengambil yang pertama:
Charlie
Perbedaan where() dan firstWhere()
where()
bisa menghasilkan:
Charlie
Henry
Ivy
Sedangkan:
firstWhere()
hanya:
Charlie
Analogi
Bayangkan kamu mencari siswa yang mendapat nilai A.
where() berkata:
“Tampilkan semua siswa yang mendapat A.”
firstWhere() berkata:
“Saya cuma butuh siswa pertama yang mendapat A.”
11. lastWhere()
Kalau:
firstWhere()
mengambil yang pertama,
maka:
lastWhere()
mengambil yang terakhir.
Contoh:
var result = names.lastWhere(
(name) => name.endsWith("y"),
);
Misalnya:
Charlie
Henry
Ivy
Yang terakhir adalah:
Ivy
Maka hasilnya:
Ivy
12. Perbedaan where, firstWhere, lastWhere
Ini penting:
| Function | Hasil |
|---|---|
where() | Semua yang cocok |
firstWhere() | Yang pertama cocok |
lastWhere() | Yang terakhir cocok |
Misalnya data:
Alice
Charlie
Henry
Ivy
dengan kondisi endsWith("y"):
where() → Charlie, Henry, Ivy
firstWhere() → Charlie
lastWhere() → Ivy
13. retainWhere()
Sekarang kita masuk ke operasi yang mengubah collection asli.
Contoh:
names.retainWhere(
(name) => name.startsWith("A"),
);
Misalnya awalnya:
[Alice, Bob, Charlie, Henry, Ivy]
Setelah:
retainWhere((name) => name.startsWith("A"))
menjadi:
[Alice]
Perbedaan where() dengan retainWhere()
Ini sangat penting.
where()
var filtered = names.where(...).toList();
Membuat hasil baru.
Collection asli:
[Alice, Bob, Charlie, Henry, Ivy]
tetap ada.
Hasil:
[Alice]
retainWhere()
names.retainWhere(...);
langsung mengubah names.
Awalnya:
[Alice, Bob, Charlie, Henry, Ivy]
Setelah:
[Alice]
Tidak membuat List hasil baru sebagai return value.
Gampangnya:
where()
↓
buat hasil filter baru
sedangkan:
retainWhere()
↓
ubah collection asli
14. removeWhere()
Kalau retainWhere() berarti:
Pertahankan yang memenuhi kondisi.
Maka removeWhere() berarti:
Hapus yang memenuhi kondisi.
Misalnya:
names.removeWhere(
(name) => name.endsWith("y"),
);
Awalnya:
[Alice, Bob, Charlie, Henry, Ivy]
Yang berakhiran y:
Charlie
Henry
Ivy
Mereka dihapus.
Hasil:
[Alice, Bob]
Perbedaan retainWhere dan removeWhere
Misalnya:
[Alice, Bob, Charlie, Henry, Ivy]
retainWhere
names.retainWhere((name) => name.endsWith("y"));
Hasil:
[Charlie, Henry, Ivy]
removeWhere
names.removeWhere((name) => name.endsWith("y"));
Hasil:
[Alice, Bob]
Jadi:
retain = pertahankan
remove = hapus
15. indexWhere()
Sekarang bukan lagi mencari datanya, tetapi mencari index dari data yang memenuhi kondisi.
Contoh:
int index = names.indexWhere(
(name) => name.endsWith("y"),
);
Misalnya:
Index Value
0 Alice
1 Bob
2 Charlie
3 Henry
4 Ivy
Yang berakhiran y:
Charlie → index 2
Henry → index 3
Ivy → index 4
indexWhere() mengambil index pertama yang memenuhi kondisi.
Hasil:
2
16. indexWhere() kalau tidak ditemukan
Ini juga perlu diingat.
Misalnya:
int index = names.indexWhere(
(name) => name.startsWith("Z"),
);
Tidak ada nama yang dimulai dengan Z.
Maka hasilnya:
-1
Jadi:
index >= 0
→ ditemukan.
index == -1
→ tidak ditemukan.
17. singleWhere()
Ini agak berbeda dan harus hati-hati.
singleWhere() berarti:
Saya yakin kondisi ini hanya cocok dengan tepat satu elemen.
Contoh:
var result = names.singleWhere(
(name) => name.startsWith("A"),
);
Kalau hanya ada:
Alice
yang memenuhi kondisi, hasilnya:
Alice
Bagaimana kalau ada dua?
Misalnya:
Alice
Adam
Bob
Charlie
Kita menjalankan:
names.singleWhere(
(name) => name.startsWith("A"),
);
Ada:
Alice
Adam
Dua data cocok.
Maka akan terjadi exception.
Kenapa?
Karena singleWhere() mengatakan:
“Saya mengharapkan tepat satu.”
Tetapi ternyata ada dua.
Bagaimana kalau tidak ada?
Kalau tidak ada yang cocok, juga bisa menghasilkan exception, kecuali kita memberikan orElse.
Contoh:
var result = names.singleWhere(
(name) => name.startsWith("Z"),
orElse: () => "Tidak ditemukan",
);
Sekarang kalau tidak ada Z:
Tidak ditemukan
18. Perbedaan firstWhere() dan singleWhere()
Ini sering tertukar.
Misalnya:
Alice
Adam
Bob
Kondisi:
name.startsWith("A")
firstWhere()
names.firstWhere((name) => name.startsWith("A"));
Hasil:
Alice
Tidak peduli ada berapa yang cocok. Dia mengambil yang pertama.
singleWhere()
names.singleWhere((name) => name.startsWith("A"));
Error karena:
Alice
Adam
dua elemen cocok.
Jadi:
firstWhere → boleh banyak, ambil pertama
singleWhere → harus tepat satu
19. lastIndexWhere()
Kalau:
indexWhere()
mencari index pertama yang cocok,
maka:
lastIndexWhere()
mencari index terakhir yang cocok.
Misalnya:
Index Value
0 Alice
1 Bob
2 Charlie
3 Henry
4 Ivy
Kondisi:
name.endsWith("y")
Yang cocok:
Charlie → 2
Henry → 3
Ivy → 4
Maka:
names.lastIndexWhere(
(name) => name.endsWith("y"),
);
menghasilkan:
4
20. lastIndexOf()
Kalau kita sudah tahu nilai yang ingin dicari, kita tidak perlu menggunakan kondisi.
Gunakan:
lastIndexOf()
Misalnya:
int index = names.lastIndexOf("Frank");
Kalau:
0 Alice
1 Bob
2 Charlie
3 Henry
4 Ivy
5 Frank
hasilnya:
5
Kalau ada nama yang sama?
Misalnya:
0 Alice
1 Bob
2 Charlie
3 Frank
4 Ivy
5 Frank
Maka:
names.lastIndexOf("Frank")
menghasilkan:
5
Karena lastIndexOf() mencari kemunculan terakhir.
Sedangkan:
names.indexOf("Frank")
akan menghasilkan:
3
21. Ringkasan operasi pada List
Ini bagian yang sebaiknya kamu simpan sebagai catatan.
| Method | Fungsi |
|---|---|
where() | Semua elemen yang cocok |
firstWhere() | Elemen pertama yang cocok |
lastWhere() | Elemen terakhir yang cocok |
retainWhere() | Pertahankan elemen yang cocok |
removeWhere() | Hapus elemen yang cocok |
indexWhere() | Index pertama yang cocok |
singleWhere() | Tepat satu elemen yang cocok |
lastIndexWhere() | Index terakhir yang cocok |
indexOf() | Index pertama dari nilai tertentu |
lastIndexOf() | Index terakhir dari nilai tertentu |
22. Sekarang bagaimana dengan Map?
Nah, ini penting.
Misalnya kita punya:
Map<String, String> namesMap = {
"name1": "Alice",
"name2": "Bob",
"name3": "Charlie",
};
Kita tidak bisa langsung melakukan:
namesMap.where(...)
Karena Map tidak menyediakan where() secara langsung seperti List.
Tetapi Map mempunyai:
keys
values
entries
Dan ketiganya bisa digunakan untuk filtering.
23. Filtering Map.keys
Misalnya:
Map<String, String> namesMap = {
"name5": "Alice",
"name6": "Bob",
"name8": "Charlie",
};
Kita bisa mengambil key:
namesMap.keys
Hasilnya secara konsep:
name5
name6
name8
Kemudian kita bisa menggunakan:
namesMap.keys.where(
(key) => key.endsWith("5"),
);
Artinya:
Cari key yang diakhiri angka 5.
Hasil:
name5
Kalau ingin menjadi List:
var result = namesMap.keys
.where((key) => key.endsWith("5"))
.toList();
24. Filtering Map.values
Kita juga bisa melakukan filter terhadap value.
Misalnya:
Map<String, String> namesMap = {
"name1": "Alice",
"name2": "Bob",
"name3": "Charlie",
};
Ambil values:
namesMap.values
Kemudian:
var result = namesMap.values
.where((name) => name.endsWith("e"))
.toList();
Kita sedang mengatakan:
Dari semua value, ambil yang berakhiran
e.
25. Filtering Map menggunakan entries
Nah, kalau kita ingin mendapatkan key DAN value sekaligus, gunakan:
entries
Misalnya:
Map<String, String> users = {
"user1": "Alice",
"user2": "Bob",
"user3": "Charlie",
};
Setiap entry berisi:
key → user1
value → Alice
Kita bisa:
var result = users.entries.where(
(entry) => entry.value.startsWith("A"),
).toList();
Artinya:
Ambil entry yang value-nya dimulai dengan A.
Hasilnya kurang lebih:
(user1, Alice)
26. entry.key dan entry.value
Ketika kita menggunakan:
users.entries
setiap elemen adalah sebuah MapEntry.
Kita bisa mengakses:
entry.key
untuk mendapatkan key.
Dan:
entry.value
untuk mendapatkan value.
Misalnya:
users.entries.where(
(entry) => entry.value.startsWith("A"),
);
Di sini kita memeriksa:
entry.value
Kalau ingin memeriksa key:
users.entries.where(
(entry) => entry.key == "user1",
);
27. Kenapa entries berguna?
Bayangkan Map:
user1 → Alice
user2 → Bob
user3 → Charlie
Kalau menggunakan:
users.keys
kita hanya mendapatkan:
user1
user2
user3
Kalau:
users.values
kita mendapatkan:
Alice
Bob
Charlie
Tetapi:
users.entries
memberikan keduanya:
user1 → Alice
user2 → Bob
user3 → Charlie
Jadi kalau filtering membutuhkan key dan value sekaligus, entries adalah pilihan yang tepat.
28. Filtering pada Set
Set jauh lebih mirip dengan List dalam hal where().
Misalnya:
Set<String> names = {
"Alice",
"Bob",
"Charlie",
"Henry",
"Ivy",
};
Kita bisa:
var result = names
.where((name) => name.endsWith("y"))
.toList();
Hasil:
[Charlie, Henry, Ivy]
Konsepnya sama:
Set
↓
where()
↓
Iterable
↓
toList()
↓
List
29. Hasil where() pada Set bisa dijadikan Set lagi
Kalau kita ingin hasilnya tetap Set:
Set<String> result = names
.where((name) => name.endsWith("y"))
.toSet();
Perhatikan perbedaannya:
.toList()
→ hasil List
sedangkan:
.toSet()
→ hasil Set
30. retainWhere() pada Set
Set juga bisa menggunakan:
retainWhere()
Misalnya:
names.retainWhere(
(name) => name.endsWith("y"),
);
Awalnya:
Alice
Bob
Charlie
Henry
Ivy
Setelah:
Charlie
Henry
Ivy
Yang dipertahankan hanya yang memenuhi kondisi.
Dan sekali lagi:
retainWhere()mengubah Set yang asli.
31. retainAll() pada Set
Ini juga penting.
Misalnya:
Set<String> names = {
"Alice",
"Bob",
"Charlie",
"Henry",
"Ivy",
};
Kita hanya ingin mempertahankan:
Alice
Bob
Kita bisa:
names.retainAll({
"Alice",
"Bob",
});
Hasil:
{Alice, Bob}
Semua yang lain dihapus.
32. Bedakan retainWhere() dan retainAll()
retainWhere()
Menggunakan kondisi:
names.retainWhere(
(name) => name.length > 4,
);
Artinya:
Pertahankan nama yang panjangnya lebih dari 4.
retainAll()
Menggunakan daftar nilai yang ingin dipertahankan:
names.retainAll({
"Alice",
"Bob",
});
Artinya:
Pertahankan hanya Alice dan Bob.
33. Gambaran besar where() pada List, Map, Set
Sekarang kita satukan semuanya.
List
names.where(
(name) => name.startsWith("A"),
);
Langsung bisa.
Set
namesSet.where(
(name) => name.startsWith("A"),
);
Langsung bisa.
Map
Tidak:
users.where(...); // ❌
Tetapi:
users.keys.where(...); // berdasarkan key
users.values.where(...); // berdasarkan value
users.entries.where(...); // berdasarkan key + value
34. Analogi sederhana
Bayangkan kamu punya kotak berisi data.
List
📦 List
Alice
Bob
Charlie
Henry
Ivy
Kamu berkata:
“Ambil semua nama yang berakhiran Y.”
where():
📦
↓ filter
Charlie
Henry
Ivy
firstWhere()
Kamu berkata:
“Saya hanya mau yang pertama.”
Charlie
lastWhere()
“Saya mau yang terakhir.”
Ivy
singleWhere()
“Saya yakin hanya ada satu.”
Kalau ternyata ada dua → exception.
removeWhere()
“Buang semua yang memenuhi kondisi.”
retainWhere()
“Pertahankan semua yang memenuhi kondisi, buang sisanya.”
35. Hal paling penting yang perlu kamu hafalkan
Kalau kamu baru belajar, jangan mencoba menghafalkan semua method sekaligus.
Fokus dulu pada 6 ini:
where()
firstWhere()
lastWhere()
removeWhere()
retainWhere()
indexWhere()
Kemudian pahami hubungan berikut:
where
↓
semua yang cocok
firstWhere
↓
yang pertama
lastWhere
↓
yang terakhir
singleWhere
↓
harus tepat satu
indexWhere
↓
index pertama
lastIndexWhere
↓
index terakhir
removeWhere
↓
hapus yang cocok
retainWhere
↓
pertahankan yang cocok
36. Contoh lengkap agar semuanya nyambung
Misalnya:
List<String> names = [
"Alice",
"Bob",
"Charlie",
"Henry",
"Ivy",
];
Semua yang berakhiran y
var result = names
.where((name) => name.endsWith("y"))
.toList();
Hasil:
[Charlie, Henry, Ivy]
Yang pertama
var result = names.firstWhere(
(name) => name.endsWith("y"),
);
Hasil:
Charlie
Yang terakhir
var result = names.lastWhere(
(name) => name.endsWith("y"),
);
Hasil:
Ivy
Index pertama
var result = names.indexWhere(
(name) => name.endsWith("y"),
);
Hasil:
2
Index terakhir
var result = names.lastIndexWhere(
(name) => name.endsWith("y"),
);
Hasil:
4
Hapus semuanya yang berakhiran y
names.removeWhere(
(name) => name.endsWith("y"),
);
Hasil:
[Alice, Bob]
🎯 Kesimpulan
Materi ini sebenarnya mengajarkan satu konsep besar:
Bagaimana memilih, mencari, mempertahankan, atau menghapus data berdasarkan sebuah kondisi.
Dan pusat dari semuanya adalah:
where()
Karena where() berarti:
collection
↓
periksa setiap elemen
↓
apakah memenuhi kondisi?
↓
YES → ambil
NO → abaikan
Contoh paling penting:
var result = names
.where((name) => name.length > 4)
.toList();
Bacanya:
“Dari
names, ambil semua nama yang panjangnya lebih dari 4 karakter, lalu ubah hasilnya menjadi List.”
Sedangkan untuk Map:
users.keys.where(...)
→ filter berdasarkan key
users.values.where(...)
→ filter berdasarkan value
users.entries.where(...)
→ filter berdasarkan key dan value.
Kalau konsep ini sudah kamu pahami, kamu sebenarnya sudah mulai masuk ke pola programming yang sangat penting: mengolah kumpulan data dengan kondisi, bukan sekadar mengambil data satu per satu.