2 个版本
0.1.1 | 2024年3月11日 |
---|---|
0.1.0 | 2024年3月11日 |
#2125 in 数据结构
20KB
313 行
理解
Rust中通过宏实现的类似于Python的列表、集合和哈希表推导式。
lib.rs
:
推导式
尽可能高效地为Rust实现类似于Python的列表、集合和哈希表推导式。
由于Python处理推导式的方式,一对一的翻译是不可能的,至少不能不依赖于克隆一切。当使用这个库时,是否克隆取决于用户。
遵守Rust的所有权和借用规则,通过值传递将消耗集合。
comp!
返回一个元素迭代器。compco!
包含一个.collect()调用。
示例
基本数组推导式
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]);
嵌套数组推导式
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]);
创建两个数组的组合,必须使用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)]);
使用过滤器创建一个向量,该向量包含所有小于3的3个索引,它们的和为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]]);
基本哈希表推导式
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)]));
哈希表推导式也可以嵌套使用,并使用过滤器或特殊的=>语法。
使用嵌套推导式时特殊的'=>'语法,在内部循环上进行操作。例如,将第一个变量作为值分配给数组中的其他数字作为键。
# 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)]));
这将相当于以下内容
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)]));