//! 269. Splitting by predicate with partition()
//!
//! `partition(pred)` splits an iterator into two collections in a single pass.
fn main() {
let nums: Vec<i32> = (1..=10).collect();
let (evens, odds): (Vec<i32>, Vec<i32>) =
nums.iter().copied().partition(|&x| x % 2 == 0);
println!("Evens: {:?}", evens);
println!("Odds: {:?}", odds);
let words = ["hi", "hello", "yo", "world", "hey", "programming"];
let (short, long): (Vec<_>, Vec<_>) = words.iter().partition(|w| w.len() <= 3);
println!("Short: {:?}", short);
println!("Long: {:?}", long);
let results: Vec<Result<i32, &str>> = vec![
Ok(1), Err("bad"), Ok(3), Err("fail"), Ok(5)
];
let (oks, errs): (Vec<_>, Vec<_>) = results.into_iter().partition(Result::is_ok);
let ok_vals: Vec<i32> = oks.into_iter().flatten().collect();
let err_msgs: Vec<&str> = errs.into_iter().map(|r| r.unwrap_err()).collect();
println!("Ok values: {:?}", ok_vals);
println!("Err values: {:?}", err_msgs);
let data = [-3i32, 1, -1, 4, -1, 5, 9, -2, 6];
let (pos, neg): (Vec<i32>, Vec<i32>) =
data.iter().copied().partition(|&x| x >= 0);
println!("Sum pos: {}, Sum neg: {}", pos.iter().sum::<i32>(), neg.iter().sum::<i32>());
}
#[cfg(test)]
mod tests {
#[test]
fn test_partition_even_odd() {
let (evens, odds): (Vec<i32>, Vec<i32>) =
(1..=6).partition(|&x| x % 2 == 0);
assert_eq!(evens, vec![2, 4, 6]);
assert_eq!(odds, vec![1, 3, 5]);
}
#[test]
fn test_partition_results() {
let v: Vec<Result<i32, i32>> = vec![Ok(1), Err(2), Ok(3)];
let (oks, errs): (Vec<_>, Vec<_>) = v.into_iter().partition(Result::is_ok);
assert_eq!(oks.len(), 2);
assert_eq!(errs.len(), 1);
}
#[test]
fn test_partition_all_true() {
let (yes, no): (Vec<i32>, Vec<i32>) =
[2i32, 4, 6].iter().copied().partition(|&x| x > 0);
assert_eq!(yes.len(), 3);
assert!(no.is_empty());
}
}
(* 269. Splitting by predicate with partition() - OCaml *)
let () =
let nums = List.init 10 (fun i -> i + 1) in
let (evens, odds) = List.partition (fun x -> x mod 2 = 0) nums in
Printf.printf "Evens: %s\n" (String.concat ", " (List.map string_of_int evens));
Printf.printf "Odds: %s\n" (String.concat ", " (List.map string_of_int odds));
let words = ["hi"; "hello"; "yo"; "world"; "hey"; "programming"] in
let (short, long) = List.partition (fun w -> String.length w <= 3) words in
Printf.printf "Short: %s\n" (String.concat ", " short);
Printf.printf "Long: %s\n" (String.concat ", " long);
let data = [-3; 1; -1; 4; -1; 5; 9; -2; 6] in
let (pos, neg) = List.partition (fun x -> x >= 0) data in
Printf.printf "Sum pos: %d, Sum neg: %d\n"
(List.fold_left (+) 0 pos)
(List.fold_left (+) 0 neg)