map과 flat_map 차이점 및 사용 예제Rust의 map과 flat_map은 이터레이터 메서드로, 각각 이터레이터의 요소에 함수를 적용하지만 중요한 차이점이 있습니다. 두 메서드의 차이점과 사용 예제를 통해 설명하겠습니다.
mapmap 메서드는 이터레이터의 각 요소에 함수를 적용하여 새로운 이터레이터를 생성합니다. 각 요소를 변환하지만 결과는 여전히 변환된 요소의 이터레이터입니다.
fn main() {
let numbers = vec![1, 2, 3, 4];
let squares: Vec<i32> = numbers.iter().map(|&x| x * x).collect();
println!("{:?}", squares); // [1, 4, 9, 16]
}
위 예제에서 map은 각 요소에 제곱 함수를 적용하여 새로운 벡터를 만듭니다.
flat_mapflat_map 메서드는 이터레이터의 각 요소에 함수를 적용하고, 이 함수는 또 다른 이터레이터를 반환해야 합니다. 그런 다음 flat_map은 이러한 내부 이터레이터를 평탄화하여 단일 이터레이터를 생성합니다.
fn main() {
let numbers = vec![1, 2, 3, 4];
let expanded: Vec<i32> = numbers.iter().flat_map(|&x| vec![x, x * 2]).collect();
println!("{:?}", expanded); // [1, 2, 2, 4, 3, 6, 4, 8]
}
위 예제에서 flat_map은 각 요소에 대해 두 개의 값을 포함하는 벡터를 반환합니다. 그런 다음 flat_map은 이 중첩된 이터레이터를 평탄화하여 단일 벡터를 만듭니다.
map: 각 요소를 변환하지만 결과는 여전히 변환된 요소의 이터레이터입니다.flat_map: 각 요소를 변환하여 새로운 이터레이터를 반환하고, 이 이터레이터들을 평탄화하여 단일 이터레이터를 만듭니다.이 예제는 각 문자열을 단어로 분할하여 모든 단어를 단일 벡터로 수집하는 방법을 보여줍니다.
map 예제fn main() {
let sentences = vec!["hello world", "rust is great"];
let words: Vec<_> = sentences.iter().map(|&s| s.split_whitespace()).collect();
println!("{:?}", words);
// 결과: [SplitWhitespace { inner: "hello world" }, SplitWhitespace { inner: "rust is great" }]
// SplitWhitespace 이터레이터가 포함된 벡터
}
flat_map 예제fn main() {
let sentences = vec!["hello world", "rust is great"];
let words: Vec<&str> = sentences.iter().flat_map(|&s| s.split_whitespace()).collect();
println!("{:?}", words); // ["hello", "world", "rust", "is", "great"]
}
위 예제에서 flat_map은 각 문자열을 단어로 분할하고, 모든 단어를 평탄화하여 단일 벡터로 수집합니다.
map과 flat_map의 차이점: Result와 함께 사용map과 flat_map의 차이는 Result 타입과 함께 사용할 때 특히 중요합니다.
map 예제:fn main() {
let input_numbers = "10 20 30 invalid 40";
let numbers: Vec<Result<i32, _>> = input_numbers
.split_ascii_whitespace()
.map(str::parse::<i32>)
.collect();
for num in &numbers {
match num {
Ok(n) => println!("Parsed number: {}", n),
Err(e) => println!("Failed to parse: {}", e),
}
}
}
위 코드는 각 요소에 대해 str::parse::<i32>를 호출하고, 그 결과(Result<i32, _>)를 그대로 유지합니다. collect()는 이를 Vec<Result<i32, _>>로 변환합니다. 파싱 실패 여부를 확인할 수 있습니다.
flat_map 예제:fn main() {
let input_numbers = "10 20 30 invalid 40";
let numbers: Vec<i32> = input_numbers
.split_ascii_whitespace()
.flat_map(str::parse::<i32>)
.collect();
for num in &numbers {
println!("Parsed number: {}", num);
}
}
위 코드는 flat_map을 사용하여 Result에서 성공한 값들만 남기고 오류를 무시합니다. flat_map은 각 요소에 대해 str::parse::<i32>를 호출하고, 성공적인 결과를 평탄화하여 단일 이터레이터로 반환합니다.
map: 각 요소에 대해 Result를 반환하고, 이를 그대로 유지합니다. 즉, 실패한 파싱 결과도 Result 형태로 벡터에 포함됩니다.flat_map: Result를 평탄화하여 성공적인 값들만 단일 이터레이터로 반환합니다. 실패한 파싱 결과는 무시됩니다.따라서, 입력 문자열에서 숫자만 추출하고 싶다면 flat_map을 사용하는 것이 더 적합합니다. 이는 성공적으로 파싱된 값들만 남기고 나머지를 무시하기 때문입니다. 반면, 파싱 실패 여부도 확인하고 싶다면 map을 사용하는 것이 적합합니다.