CodeBlanks Logo Icon CodeBlanks

Kayıt listeleme

Iterator ile post listesi üretirsin.

Kayıt listeleme

Okunan yazılar üzerinde sorgular yineleyici zincirleriyle kurulur. Her sorgu bir yüklem (predicate) closure'ıdır ve birleştirilebilir:

fn yayindakiler<'a>(v: &'a [Yazi], etiket: &str) -> Vec<&'a Yazi> {
    v.iter()
        .filter(|y| y.yayinda)
        .filter(|y| y.etiketler.iter().any(|e| e == etiket))
        .collect()
}

Sonuç referans vektörüdür; yazılar kopyalanmaz. Dönüşün ömrü girdi dilimine bağlı olduğu için 'a yazılır.

Sıralama ve özet

Referans vektörü de sıralanabilir; sort_by_key ile konuya göre:

let mut liste = yayindakiler(&yazilar, "rust");
liste.sort_by_key(|y| y.konu.clone());
for y in &liste {
    println!("{}. {} ({})", y.id, y.konu, y.yazar);
}

sort_by(|a, b| a.konu.cmp(&b.konu)) klonlamadan aynı işi yapar.

Uygulama Yayındaki Rust yazıları

Hazır veri_seti() verisi ile yukarıdaki yayindakiler fonksiyonunu yaz. "rust" etiketli yayındaki yazıları id. konu (yazar) biçiminde yazdır.

Başlangıç kodu

main.rs
#[derive(Debug, Clone)]
struct Yazi {
    id: u32,
    konu: String,
    yazar: String,
    etiketler: Vec<String>,
    yayinda: bool,
}

fn veri_seti() -> Vec<Yazi> {
    let y = |id, konu: &str, yazar: &str, et: &[&str], yayinda| Yazi {
        id,
        konu: konu.to_string(),
        yazar: yazar.to_string(),
        etiketler: et.iter().map(|e| e.to_string()).collect(),
        yayinda,
    };
    vec![
        y(1, "Rust ile başlangıç", "ece", &["rust", "giriş"], true),
        y(2, "Sahiplik", "can", &["rust"], false),
        y(3, "Web sunucusu", "ece", &["rust", "web"], true),
        y(4, "Python notları", "ali", &["python"], true),
    ]
}

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
#[derive(Debug, Clone)]
struct Yazi {
    id: u32,
    konu: String,
    yazar: String,
    etiketler: Vec<String>,
    yayinda: bool,
}

fn veri_seti() -> Vec<Yazi> {
    let y = |id, konu: &str, yazar: &str, et: &[&str], yayinda| Yazi {
        id,
        konu: konu.to_string(),
        yazar: yazar.to_string(),
        etiketler: et.iter().map(|e| e.to_string()).collect(),
        yayinda,
    };
    vec![
        y(1, "Rust ile başlangıç", "ece", &["rust", "giriş"], true),
        y(2, "Sahiplik", "can", &["rust"], false),
        y(3, "Web sunucusu", "ece", &["rust", "web"], true),
        y(4, "Python notları", "ali", &["python"], true),
    ]
}

fn yayindakiler<'a>(v: &'a [Yazi], etiket: &str) -> Vec<&'a Yazi> {
    v.iter()
        .filter(|y| y.yayinda)
        .filter(|y| y.etiketler.iter().any(|e| e == etiket))
        .collect()
}

fn main() {
    let yazilar = veri_seti();
    for y in yayindakiler(&yazilar, "rust") {
        println!("{}. {} ({})", y.id, y.konu, y.yazar);
    }
}

Beklenen çıktı

1. Rust ile başlangıç (ece)
3. Web sunucusu (ece)

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Neden burada ömür açıklaması gerekiyor?

  • Gerekmez
  • İki referans parametresi var; dönüşün hangisine bağlı olduğu belirsiz Doğru cevap
  • Vec ömür ister
  • filter ömür ister

Açıklama: Elision kuralları iki referans parametrede dönüş ömrünü belirleyemez; dönüşün v'ye bağlı olduğu açıkça söylenir.

2 Etiket var mı?

Soru
.filter(|y| y.etiketler.iter().____(|e| e == etiket))
Cevap
.filter(|y| y.etiketler.iter().any(|e| e == etiket))

Açıklama: any, koşulu sağlayan en az bir eleman varsa true döndürür.

3 Sorgu ve sonuç (örnek veri)

Kavram Anlamı
yayında + "rust" 1, 3
yayında + "python" 4
yayında değil 2
"web" 3

Orta seviye bölümündeki tüm dersler