//! 264. Conditional stopping with take_while()
//!
//! `take_while(pred)` yields elements until the predicate first returns false.
fn main() {
let nums = [1i32, 2, 3, 4, 5, 6, 7, 8, 9];
let small: Vec<i32> = nums.iter().copied().take_while(|&x| x < 5).collect();
println!("Less than 5: {:?}", small);
let data = [3i32, 1, 4, 1, -5, 9, -2, 6];
let positives: Vec<i32> = data.iter().copied().take_while(|&x| x > 0).collect();
println!("Leading positives: {:?}", positives);
// Works on infinite iterators
let triangulars: Vec<u64> = (1u64..)
.take_while(|&n| n * (n + 1) / 2 < 30)
.collect();
println!("n where triangular(n)<30: {:?}", triangulars);
let input = "hello123world";
let word: String = input.chars().take_while(|c| c.is_alphabetic()).collect();
println!("Leading word: '{}'", word);
let sorted_words = ["ant", "bear", "cat", "dog", "elephant"];
let short: Vec<_> = sorted_words.iter().take_while(|w| w.len() <= 3).collect();
println!("Short words: {:?}", short);
}
#[cfg(test)]
mod tests {
#[test]
fn test_take_while_basic() {
let result: Vec<i32> = [1, 2, 3, 4, 5].iter().copied()
.take_while(|&x| x < 4).collect();
assert_eq!(result, vec![1, 2, 3]);
}
#[test]
fn test_take_while_none_match() {
let result: Vec<i32> = [-1i32, 2, 3].iter().copied()
.take_while(|&x| x > 0).collect();
assert!(result.is_empty());
}
#[test]
fn test_take_while_stops_early() {
let result: Vec<i32> = [1i32, 2, 5, 1, 2].iter().copied()
.take_while(|&x| x < 3).collect();
assert_eq!(result, vec![1, 2]);
}
#[test]
fn test_take_while_infinite() {
let result: Vec<u32> = (0u32..).take_while(|&x| x < 5).collect();
assert_eq!(result, vec![0, 1, 2, 3, 4]);
}
}
(* 264. Conditional stopping with take_while() - OCaml *)
let rec take_while pred = function
| [] -> []
| x :: xs -> if pred x then x :: take_while pred xs else []
let () =
let nums = [1; 2; 3; 4; 5; 6; 7; 8; 9] in
let small = take_while (fun x -> x < 5) nums in
Printf.printf "Less than 5: %s\n"
(String.concat ", " (List.map string_of_int small));
let data = [3; 1; 4; 1; -5; 9; -2; 6] in
let positives = take_while (fun x -> x > 0) data in
Printf.printf "Leading positives: %s\n"
(String.concat ", " (List.map string_of_int positives));
let naturals = List.init 100 (fun i -> i + 1) in
let triangular = take_while (fun n -> n * (n+1) / 2 < 30) naturals in
Printf.printf "n where triangular(n) < 30: %s\n"
(String.concat ", " (List.map string_of_int triangular))