如何从两个同长度Vec<f64>生成Vec<[f64;2]>用于egui绘图
将两个Vec压缩为Vec<[f64;2]>(适配egui PlotPoints)
问题场景
我有两个长度相同的Vec<f64>,需要把它们合并成Vec<[f64;2]>类型(而非元组类型),因为egui的PlotPoints::from方法要求传入这种格式的参数。目前已经能通过zip得到Vec<(&f64, &f64)>,也知道单个Vec<f64>可以用chunks_exact处理,但不清楚两个Vec的情况该怎么操作。
解决方案
核心思路是用zip将两个Vec的元素配对,再通过map把每一对元组转换为固定大小数组[f64;2]。根据是否需要保留原Vec的所有权,有两种常见实现方式:
1. 保留原Vec所有权(引用迭代)
如果之后还要使用vec1和vec2,用iter()生成引用迭代器,解引用或克隆获取元素副本后转换为数组:
let vec1: Vec<f64> = vec![1.,2.,3.,4.,5.,6.]; let vec2: Vec<f64> = vec![6.,5.,4.,3.,2.,1.]; let graph: Vec<[f64;2]> = vec1.iter() .zip(vec2.iter()) .map(|(x, y)| [*x, *y]) // 或用(x.cloned(), y.cloned())后解构 .collect(); println!("{:?}", graph); // 输出: [[1.0, 6.0], [2.0, 5.0], [3.0, 4.0], [4.0, 3.0], [5.0, 2.0], [6.0, 1.0]]
2. 转移原Vec所有权(into迭代)
如果原Vec之后不再使用,用into_iter()转移所有权,直接将元组转为数组,避免额外复制:
let vec1: Vec<f64> = vec![1.,2.,3.,4.,5.,6.]; let vec2: Vec<f64> = vec![6.,5.,4.,3.,2.,1.]; let graph: Vec<[f64;2]> = vec1.into_iter() .zip(vec2.into_iter()) .map(|(x, y)| [x, y]) .collect(); println!("{:?}", graph); // 输出: [[1.0, 6.0], [2.0, 5.0], [3.0, 4.0], [4.0, 3.0], [5.0, 2.0], [6.0, 1.0]]
3. 适配egui绘图的完整示例
把转换后的数组直接传入PlotPoints::from即可:
let vec1: Vec<f64> = vec![1.,2.,3.,4.,5.,6.]; let vec2: Vec<f64> = vec![6.,5.,4.,3.,2.,1.]; let graph: Vec<[f64;2]> = vec1.into_iter() .zip(vec2.into_iter()) .map(|(x, y)| [x, y]) .collect(); let inner = my_plot.show(ui, |plot_ui| { plot_ui.line(Line::new(PlotPoints::from(graph)).name("curve")); }); plot_rect = Some(inner.response.rect);
补充说明
- 因为
f64实现了Copytrait,解引用或克隆的开销极小;如果是非Copy类型,需根据场景选择克隆或转移所有权。 - 确保两个Vec长度相同,否则
zip会以较短的Vec长度为准,忽略较长Vec的剩余元素。
内容的提问来源于stack exchange,提问作者round-and-round
相关产品推荐
相关产品推荐

