// 091: Zip and Unzip
fn main() {
// zip
let a = vec![1, 2, 3];
let b = vec!["a", "b", "c"];
let zipped: Vec<_> = a.iter().zip(b.iter()).collect();
println!("zip: {:?}", zipped);
// unzip
let pairs = vec![(1, "a"), (2, "b"), (3, "c")];
let (nums, strs): (Vec<i32>, Vec<&str>) = pairs.into_iter().unzip();
println!("unzip: {:?} {:?}", nums, strs);
// zip_with
let sums: Vec<i32> = [1, 2, 3].iter().zip([10, 20, 30].iter()).map(|(a, b)| a + b).collect();
println!("zip_with +: {:?}", sums);
}
#[cfg(test)]
mod tests {
#[test]
fn test_zip() {
let v: Vec<_> = [1, 2, 3].iter().zip(["a", "b", "c"].iter()).collect();
assert_eq!(v, vec![(&1, &"a"), (&2, &"b"), (&3, &"c")]);
}
#[test]
fn test_zip_unequal() {
let v: Vec<_> = [1, 2].iter().zip([10, 20, 30].iter()).collect();
assert_eq!(v.len(), 2);
}
#[test]
fn test_unzip() {
let (a, b): (Vec<i32>, Vec<&str>) = vec![(1, "a"), (2, "b")].into_iter().unzip();
assert_eq!(a, vec![1, 2]);
assert_eq!(b, vec!["a", "b"]);
}
#[test]
fn test_zip_with() {
let v: Vec<i32> = [1, 2, 3].iter().zip([10, 20, 30].iter()).map(|(a, b)| a + b).collect();
assert_eq!(v, vec![11, 22, 33]);
}
}
(* 091: Zip and Unzip *)
(* Approach 1: Zip two lists *)
let rec zip l1 l2 =
match l1, l2 with
| [], _ | _, [] -> []
| x :: xs, y :: ys -> (x, y) :: zip xs ys
(* Approach 2: Unzip pairs *)
let unzip pairs =
List.fold_right (fun (a, b) (la, lb) -> (a :: la, b :: lb)) pairs ([], [])
(* Approach 3: Zip with function *)
let rec zip_with f l1 l2 =
match l1, l2 with
| [], _ | _, [] -> []
| x :: xs, y :: ys -> f x y :: zip_with f xs ys
(* Tests *)
let () =
assert (zip [1; 2; 3] ["a"; "b"; "c"] = [(1, "a"); (2, "b"); (3, "c")]);
assert (zip [1; 2] [10; 20; 30] = [(1, 10); (2, 20)]);
assert (unzip [(1, "a"); (2, "b")] = ([1; 2], ["a"; "b"]));
assert (zip_with ( + ) [1; 2; 3] [10; 20; 30] = [11; 22; 33]);
Printf.printf "โ All tests passed\n"