map, filter, collect
Преобразование последовательностей
«map, filter, collect» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.
Преобразование последовательностей
Три метода выполняют большую часть работы в конвейерах итераторов: map преобразует каждый элемент, filter оставляет некоторые элементы, а collect собирает результаты в коллекцию.
Вместе они заменяют множество ручных циклов короткими и понятными цепочками.
map: один элемент на входе, один на выходе
map применяет замыкание к каждому элементу и выдаёт преобразованное значение. Количество элементов не меняется — меняются только их значения.
Метод ленивый, поэтому замыкание запускается только при потреблении итератора.
fn main() {
let nums = vec![1, 2, 3];
let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
println!("{:?}", doubled);
}map может изменить тип
Выходной тип map не обязан совпадать с входным. Здесь мы превращаем числа в строки.
Поэтому map отлично подходит для преобразования данных из одной формы в другую.
fn main() {
let nums = vec![1, 2, 3];
let labels: Vec<String> = nums.iter().map(|x| format!("n{}", x)).collect();
println!("{:?}", labels);
}filter: оставляем нужное
filter принимает замыкание, возвращающее bool. Элементы, для которых оно возвращает true, сохраняются, остальные отбрасываются.
Замыкание получает ссылку, поэтому часто нужно разыменовать её с помощью * или использовать сопоставление с образцом.
fn main() {
let nums = vec![1, 2, 3, 4, 5, 6];
let evens: Vec<i32> = nums.into_iter().filter(|x| x % 2 == 0).collect();
println!("{:?}", evens);
}Объединение map и filter
Адаптеры можно свободно объединять в цепочки. Порядок важен: каждый элемент проходит через цепочку сверху вниз.
Здесь мы оставляем чётные числа, а затем возводим оставшиеся в квадрат.
fn main() {
let result: Vec<i32> = (1..=6)
.filter(|x| x % 2 == 0)
.map(|x| x * x)
.collect();
println!("{:?}", result);
}collect в Vec
collect потребляет итератор и создаёт коллекцию. Поскольку возможны разные типы коллекций, обычно нужно указать целевой тип.
Синтаксис турбовилки collect::<Vec<_>>() — альтернатива указанию типа переменной.
fn main() {
let squares = (1..=4).map(|x| x * x).collect::<Vec<i32>>();
println!("{:?}", squares);
}collect в String
collect работает не только с векторами. Итератор из char можно собрать в String.
Rust использует целевой тип, чтобы определить способ сборки элементов.
fn main() {
let shouted: String = "hello".chars().map(|c| c.to_ascii_uppercase()).collect();
println!("{}", shouted);
}collect в HashMap
Итератор из кортежей «ключ-значение» можно собрать в HashMap. Объединяйте элементы в пары с помощью zip или создавайте кортежи в map.
Это удобный способ создавать таблицы поиска из двух параллельных последовательностей.
use std::collections::HashMap;
fn main() {
let map: HashMap<i32, i32> = (1..=3).map(|x| (x, x * x)).collect();
println!("{:?}", map.get(&2));
}Объединяем все три метода
Типичный конвейер читается как предложение: взять элементы, отфильтровать их, преобразовать и собрать.
Здесь мы оставляем слова длиннее трёх букв и переводим их в верхний регистр.
fn main() {
let words = vec!["hi", "rust", "go", "code"];
let kept: Vec<String> = words
.into_iter()
.filter(|w| w.len() > 3)
.map(|w| w.to_uppercase())
.collect();
println!("{:?}", kept);
}filter_map: фильтрация и преобразование одновременно
filter_map применяет замыкание, возвращающее Option. Значение Some(v) сохраняется и извлекается, а None отбрасывается.
Это особенно удобно при разборе данных, когда некоторые входные значения могут быть недопустимыми.
fn main() {
let inputs = vec!["1", "two", "3"];
let nums: Vec<i32> = inputs
.into_iter()
.filter_map(|s| s.parse::<i32>().ok())
.collect();
println!("{:?}", nums);
}Почему этот шаблон эффективен
Конвейеры map/filter/collect декларативны: они описывают, что Вы хотите получить, а не как выполнять цикл. Они помогают избежать ошибок на единицу и промежуточного изменяемого состояния.
А благодаря ленивости между этапами не создаются временные векторы.
Быстрая проверка
Проверьте свои знания о преобразовании последовательностей.
Повторение
Теперь Вы умеете строить полноценные конвейеры итераторов:
mapпреобразует каждый элемент и может изменить его типfilterоставляет элементы, для которых предикат возвращаетtruecollectсобирает результаты вVec,String,HashMapи другие коллекцииfilter_mapодновременно фильтрует и преобразует элементы с помощьюOption
Часто задаваемые вопросы
Урок «map, filter, collect» бесплатный?
Да — полный текст урока «map, filter, collect» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.
Чему я научусь в уроке «map, filter, collect»?
Преобразование последовательностей Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «map, filter, collect»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Трейт Iterator
- map, filter, collect
- Адаптеры и потребители
- Пользовательские итераторы