↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`

3 dk okuma #dart
Dizi · 18/64 Dart Türkçe Tutorial
  1. Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
  2. Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
  3. Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
  4. Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
  5. Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
  6. Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
  7. Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
  8. Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
  9. Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
  10. Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
  11. Bölüm 3 — Konu 11: `if / else if / else`
  12. Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
  13. Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
  14. Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
  15. Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
  16. Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
  17. Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
  18. Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
  19. Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
  20. Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
  21. Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
  22. Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
  23. Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
  24. Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
  25. Bölüm 5 — Konu 26: Recursion (Özyineleme)
  26. Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
  27. Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
  28. Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
  29. Bölüm 6 — Konu 30: Getter / Setter
  30. Bölüm 6 — Konu 31: Statik Üyeler (`static`)
  31. Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
  32. Bölüm 7 — Konu 33: Metod Override Etme, `@override`
  33. Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
  34. Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
  35. Bölüm 7 — Konu 36: Mixin (`with`)
  36. Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
  37. Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
  38. Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
  39. Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
  40. Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
  41. Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
  42. Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
  43. Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
  44. Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
  45. Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
  46. Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
  47. Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
  48. Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
  49. Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
  50. Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
  51. Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
  52. Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
  53. Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
  54. Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
  55. Bölüm 12 — Konu 56: Extension Methods
  56. Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
  57. Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
  58. Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
  59. Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
  60. Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
  61. Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
  62. Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
  63. Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
  64. Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
Dizinin sayfası →
İçindekiler 8 başlık
  1. for-in — Dil Yapısı (Language Construct)
  2. forEach — Bir Metod (Higher-Order Function)
  3. Ne Zaman Hangisi Kullanılır?
  4. İndeksle Birlikte Gezinme — asMap() Kalıbı
  5. Map Üzerinde forEach — Tekrar Hatırlatma
  6. Performans Notu
  7. 🎯 Bu Dersten Çıkarılması Gerekenler
  8. 📝 Ödevler

Önceki üç derste List, Set ve Map üzerinde gezinme örneklerini zaten gördün. Bu derste bu iki yaklaşımı (for-in ve forEach) doğrudan karşılaştırıp aralarındaki kritik farkları netleştireceğiz — çünkü bu fark, ileride hata ayıklarken kafa karıştırabilir.

for-in — Dil Yapısı (Language Construct)

dart
void main() {
  List<String> meyveler = ["Elma", "Armut", "Muz"];

  for (var meyve in meyveler) {
    print(meyve);
  }
}

for-in, Dart dilinin kendi sözdizimine ait bir yapıdır (if, while gibi). Bu, önemli bir sonuç doğurur: for-in içinde break ve continue kullanılabilir.

dart
void main() {
  List<int> sayilar = [1, 2, 3, 4, 5];

  for (var sayi in sayilar) {
    if (sayi == 3) break; // ✅ çalışır
    print(sayi); // 1, 2
  }
}

forEach — Bir Metod (Higher-Order Function)

dart
void main() {
  List<String> meyveler = ["Elma", "Armut", "Muz"];

  meyveler.forEach((meyve) {
    print(meyve);
  });
}

forEach ise for-in'in aksine bir dil yapısı değil, List/Set/Map sınıflarının bir metodudur. Parametre olarak bir fonksiyon alır ve bu fonksiyonu her eleman için çağırır. Bunun kritik bir sonucu var: forEach içinde break veya continue kullanamazsın:

dart
void main() {
  List<int> sayilar = [1, 2, 3, 4, 5];

  sayilar.forEach((sayi) {
    if (sayi == 3) break; // ❌ HATA! forEach içinde break kullanılamaz
    print(sayi);
  });
}

Neden? Çünkü break/continue, sadece gerçek döngü yapılarında (for, while, do-while, for-in) anlamlıdır — forEach'e verdiğin şey aslında sıradan bir fonksiyondur, ve bir fonksiyonun içinden "dışarıdaki döngüyü durdur" demenin dilde bir karşılığı yoktur. Eğer forEach içinde erken çıkmak istiyorsan, return kullanabilirsin ama bu sadece o anki fonksiyon çağrısını sonlandırır, tüm döngüyü değil:

dart
void main() {
  List<int> sayilar = [1, 2, 3, 4, 5];

  sayilar.forEach((sayi) {
    if (sayi == 3) return; // sadece bu iterasyonu atlar, continue gibi davranır
    print(sayi); // 1, 2, 4, 5 (3 atlanır ama döngü durmaz)
  });
}

Bu davranış continue'ya benzer ama break'in bir karşılığı yoktur — eğer gerçekten erken çıkmak istiyorsan, forEach yerine for-in kullanmalısın.

Ne Zaman Hangisi Kullanılır?

Durum Önerilen
Erken çıkış (break) gerekebilir for-in
Belirli elemanları atlamak (continue mantığı) yeterli İkisi de olur, forEach biraz daha kısa
Sadece her elemanla bir işlem yapmak, akışı değiştirmeye gerek yok forEach — daha fonksiyonel/kısa okunur
İndekse de ihtiyaç var Aşağıda göreceğimiz asMap() veya klasik for

İndeksle Birlikte Gezinme — asMap() Kalıbı

for-in ve forEach, sana doğrudan elemanın indeksini vermez. Eğer hem elemana hem indeksine ihtiyacın varsa birkaç seçeneğin var:

1. Klasik for ile (indeks zaten elinde):

dart
void main() {
  List<String> meyveler = ["Elma", "Armut", "Muz"];

  for (int i = 0; i < meyveler.length; i++) {
    print("$i: ${meyveler[i]}");
  }
}

2. asMap() ile (daha fonksiyonel bir yaklaşım):

dart
void main() {
  List<String> meyveler = ["Elma", "Armut", "Muz"];

  meyveler.asMap().forEach((index, meyve) {
    print("$index: $meyve");
  });
  // 0: Elma
  // 1: Armut
  // 2: Muz
}

asMap(), listeyi geçici olarak bir Map<int, String>'e çevirir (anahtarlar indeksler, değerler elemanlar olur), böylece forEach ile hem indekse hem değere erişebilirsin.

Map Üzerinde forEach — Tekrar Hatırlatma

Bir önceki derste gördüğümüz gibi, Map.forEach iki parametreli bir fonksiyon alır:

dart
void main() {
  Map<String, int> yaslar = {"Ahmet": 25, "Ayşe": 30};

  yaslar.forEach((isim, yas) {
    print("$isim: $yas");
  });
}

Burada da aynı kural geçerli — break/continue kullanılamaz, sadece return ile o iterasyon atlanabilir.

Performans Notu

Pratikte, for-in ile forEach arasında büyük bir performans farkı genelde yoktur — ikisi de benzer verimlilikte çalışır. Seçim genelde okunabilirlik ve ihtiyaca göre yapılır: erken çıkış gerekiyorsa for-in, yoksa forEach daha "fonksiyonel" ve kısa bir stil sunar. Bölüm 11'de göreceğimiz map, where, reduce gibi fonksiyonel metodlarla birlikte forEach, Dart'ın fonksiyonel programlama yaklaşımının bir parçasıdır.


🎯 Bu Dersten Çıkarılması Gerekenler

  • for-in: dil yapısıdır, break/continue kullanılabilir.
  • forEach: bir metoddur (fonksiyon alır), break/continue kullanılamaz — sadece return ile o iterasyon atlanabilir (continue gibi davranır, break'in karşılığı yoktur).
  • Erken çıkış ihtiyacı varsa kesinlikle for-in kullanılmalı.
  • İndekse ihtiyaç varsa klasik for veya asMap().forEach() kullanılabilir.
  • İkisi arasında performans farkı genelde önemsizdir — seçim okunabilirlik ve ihtiyaca göre yapılır.

📝 Ödevler

  • [ ] Bir sayı listesinde for-in kullanarak, 50'den büyük ilk sayıyı bulduğunda break ile döngüyü durduran bir örnek yaz.
  • [ ] Aynı senaryoyu forEach ile yapmaya çalış, break'in neden çalışmadığını gözlemle ve hatayı yorumla.
  • [ ] asMap().forEach() kullanarak bir liste üzerinde hem indeks hem değeri aynı anda yazdır.
  • [ ] Bir Map üzerinde forEach içinde return kullanarak belirli bir anahtarı (örn. değeri 0 olanları) atlayan bir örnek yaz.

Artık üç temel koleksiyon tipini (List, Set, Map) ve üzerlerinde gezinme yöntemlerini biliyorsun. Bölüm 4'ün son konusu olan spread operatörü ve collection if/for, koleksiyonları daha da esnek ve kısa şekilde oluşturmanı sağlayacak — özellikle Flutter'da widget listeleri oluştururken çok sık kullanacağın bir özellik.

Sıradaki konu: Bölüm 4 — Konu 20: Spread Operatörü (..., ...?) ve Collection If/For