2 releases
0.1.1 | Mar 11, 2024 |
---|---|
0.1.0 | Mar 11, 2024 |
#2542 in Data structures
20KB
313 lines
Comprehend
Python like list, set and hashmap comprehensions in Rust via macros.
lib.rs
:
Comprehension
Python like list, set and hashmap comprehensions for Rust as efficiently as possible.
Due to how Python handles comprehensions, a one to one translation is not possible, atleast not without resorting to cloning everything. When using this library, its up to the user to clone if necessary.
Upholds Rust ownerships and borrow rules, passing by value WILL consume the collection.
comp!
returns a iterator over the elements. compco!
includes a .collect() call.
Examples
Basic array comprehension
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let y: Vec<_> = comp![2*x, for x in v].collect();
assert_eq!(y, vec![2, 4,6, 8, 10, 12, 14, 16, 18, 20]);
Nested array comprehension
let v = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let y: Vec<_> = comp![2*p, for x in v, for p in x].collect();
assert_eq!(y, vec![2, 4, 6, 8, 10, 12, 14, 16, 18]);
Creating combinations of two arrays, must use clone!
let v = vec![1, 2];
let z = vec![3,4];
let y: Vec<_> = comp![(x,y), for x in v, for y in z.clone()].collect();
assert_eq!(y,vec![(1,3),(1,4),(2,3),(2,4)]);
Use with filters Create a vector of vectors of 3 indices which are all less than 3, and add up to 4.
let y: Vec<_> = comp![vec![i, j, k], for i in 0..3, for j in 0..3, for k in 0..3, if i+j+k == 4].collect();
assert_eq!(y,vec![[0,2,2],[1,1,2],[1,2,1],[2,0,2],[2,1,1],[2,2,0]]);
Basic hashmap comprehension
let v = vec![1, 2, 3, 4];
let y: HashMap<_,_> = comp!{x=>2*x, for x in v}.collect();
assert_eq!(y, HashMap::from([(1, 2), (2, 4), (3, 6), (4, 8)]));
Hashmap comprehension can be also nested used with filters or the special => syntax.
Special '=>' syntax when using nested comprehensions, to do an operation on an inner loop. For example assign the first variable as value to the other numbers as keys in the array.
# use std::collections::HashMap;
# use comprehend::comp;
let v: Vec<Vec<_>> = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
#[allow(redundant_semicolons)]
let y: HashMap<i32,i32> =
comp![p=>z.unwrap(), for x in v => {let mut y = x.into_iter(); let z = y.next();}, for p in y].collect();
assert_eq!(y, HashMap::from([(2, 1), (3, 1), (5, 4), (6, 4), (8, 7), (9, 7)]));
Would be equivalent to this:
let v: Vec<Vec<_>> = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
#[allow(redundant_semicolons)]
let y: HashMap<i32,i32> =
comp![{let mut y = x.into_iter(); let z = y.next(); comp![p=>z.unwrap(),for p in y]}, for x in v].flatten().collect();
assert_eq!(y, HashMap::from([(2, 1), (3, 1), (5, 4), (6, 4), (8, 7), (9, 7)]));