Rust

Итераторы и коллекции

Algonexys · 07.08.2026 · 👁 1

Ленивые цепочки преобразований, группировка в HashMap и сортировка без лишних аллокаций.

Код

use std::collections::HashMap;

#[derive(Debug, Clone)]
struct Order {
    id: u32,
    user: String,
    total: u32,
}

fn main() {
    let orders = vec![
        Order { id: 1, user: "ivan".into(), total: 1200 },
        Order { id: 2, user: "anna".into(), total: 450 },
        Order { id: 3, user: "ivan".into(), total: 890 },
    ];

    // Фильтрация и сумма — один проход, без промежуточных векторов
    let revenue: u32 = orders.iter().filter(|o| o.total > 500).map(|o| o.total).sum();
    println!("Выручка: {revenue}");

    // Группировка по пользователю
    let mut by_user: HashMap<&str, Vec<&Order>> = HashMap::new();
    for order in &orders {
        by_user.entry(&order.user).or_default().push(order);
    }

    // Суммы по пользователю через fold
    let totals = orders.iter().fold(HashMap::<&str, u32>::new(), |mut acc, o| {
        *acc.entry(&o.user).or_insert(0) += o.total;
        acc
    });
    println!("{totals:?}");

    // Сортировка по нескольким ключам
    let mut sorted = orders.clone();
    sorted.sort_by(|a, b| b.total.cmp(&a.total).then(a.user.cmp(&b.user)));

    // Разделение на две группы
    let (big, small): (Vec<_>, Vec<_>) = orders.iter().partition(|o| o.total >= 1000);
    println!("Крупных: {}, мелких: {}", big.len(), small.len());

    // Поиск максимума
    if let Some(top) = orders.iter().max_by_key(|o| o.total) {
        println!("Крупнейший заказ: #{} на {}", top.id, top.total);
    }
}