RUST · 심층 가이드
Rust 컬렉션 완전 정리
map과 filter부터 groupBy 직접 구현, sliding window, partition까지 Rust 이터레이터로 컬렉션을 다루는 20가지 패턴을 정리했습니다.
다른 언어에서 넘어오면 Rust 컬렉션에서 가장 먼저 걸리는 것은 iter(), into_iter(), iter_mut()의 구분입니다. 각각 참조를 빌려오고, 소유권을 가져가고, 가변 참조를 내주는 서로 다른 동작인데 이름이 비슷해 섞어 쓰기 쉽습니다. 원본을 나중에 또 쓸 계획이라면 into_iter()는 그 자리에서 컬렉션을 소비해 버린다는 점을 먼저 기억하는 편이 낫습니다.
순서는 변환 축부터 잡으면 편합니다. map 변환과 filter 필터링, reduce 합계가 기본 어댑터의 골격이고, 여기에 zip 묶기와 flatten 펼치기가 붙으면 중첩 구조를 평평하게 다루는 감이 생깁니다. 그다음 groupBy 구현과 빈도표 만들기를 보십시오. Rust 표준 라이브러리에는 groupBy가 없어 HashMap의 entry API로 직접 만들어야 하는데, 이 과정이 소유권과 기본값 삽입을 한 번에 이해하게 해 줍니다.
이터레이터 어댑터는 게으르다는 점이 함정입니다. map이나 filter만 연결해 두고 collect()나 for로 소비하지 않으면 클로저는 한 번도 실행되지 않습니다. 컴파일러가 #[must_use] 경고를 주지만 결과를 변수에 담아 두면 경고도 사라집니다. 또 collect()는 무엇으로 모을지 스스로 알지 못하므로, 목표 타입을 변수 쪽에 적거나 collect::<Vec<_>>()처럼 터보피시로 지정해야 합니다.
01map 변환
Rust에서 map 변환 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// map 변환
fn main() {
let items = vec![1, 2, 3, 1];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
02filter 필터링
Rust에서 filter 필터링 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// filter 필터링
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
03reduce 합계
Rust에서 reduce 합계 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// reduce 합계
fn main() {
let items = vec![1, 2, 3, 3];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
04첫 요소 찾기
Rust에서 첫 요소 찾기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 첫 요소 찾기
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
05Set 중복 제거
Rust에서 Set 중복 제거 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// Set 중복 제거
fn main() {
let items = vec![1, 2, 3, 5];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
06단어 수 세기
Rust에서 단어 수 세기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 단어 수 세기
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
07스택 구현
Rust에서 스택 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 스택 구현
fn main() {
let items = vec![1, 2, 3, 7];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
08큐 구현
Rust에서 큐 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 큐 구현
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
092차원 배열 합계
Rust에서 2차원 배열 합계 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 2차원 배열 합계
fn main() {
let items = vec![1, 2, 3, 9];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
10groupBy 구현
Rust에서 groupBy 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// groupBy 구현
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
11flatten 펼치기
Rust에서 flatten 펼치기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// flatten 펼치기
fn main() {
let items = vec![1, 2, 3, 11];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
12zip 묶기
Rust에서 zip 묶기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// zip 묶기
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
13chunk 나누기
Rust에서 chunk 나누기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// chunk 나누기
fn main() {
let items = vec![1, 2, 3, 13];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
14key 기준 정렬
Rust에서 key 기준 정렬 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// key 기준 정렬
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
15빈도표 만들기
Rust에서 빈도표 만들기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 빈도표 만들기
fn main() {
let items = vec![1, 2, 3, 15];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
16대소문자 무시 중복 제거
Rust에서 대소문자 무시 중복 제거 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// 대소문자 무시 중복 제거
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
17sliding window
Rust에서 sliding window 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// sliding window
fn main() {
let items = vec![1, 2, 3, 17];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
18pair 목록을 맵으로 변환
Rust에서 pair 목록을 맵으로 변환 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// pair 목록을 맵으로 변환
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
19reverse 복사
Rust에서 reverse 복사 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// reverse 복사
fn main() {
let items = vec![1, 2, 3, 19];
let doubled: Vec<i32> = items.iter().map(|value| value * 2).collect();
println!("{:?}", doubled);
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
20partition 나누기
Rust에서 partition 나누기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
Rust code
// partition 나누기
use std::collections::HashSet;
fn main() {
let tags: HashSet<&str> = ["rust", "cargo", "rust", "ts"].into_iter().collect();
println!("{}", tags.len());
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
정리하며
- iter는 빌리고 into_iter는 소비하므로 원본 재사용 계획에 맞춰 고릅니다
- 어댑터는 게을러서 collect나 for로 소비해야 실제로 실행됩니다
- groupBy는 HashMap entry API로 직접 만들며 기본값 삽입을 함께 익힙니다
- collect는 목표 타입을 명시해야 하며 터보피시가 가장 확실합니다
더 깊이 들어가고 싶다면 Rust 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.