鉴于内部Vec 是一列,那么您可以将fold() 和sum() 交叉。
fn col_means(mat: &[Vec<f64>]) -> Vec<f64> {
assert!(!mat.is_empty());
let col_len = mat[0].len();
let mut col_means = mat.iter().fold(vec![0.0; col_len], |mut col_means, row| {
row.iter()
.enumerate()
.for_each(|(i, cell)| col_means[i] += cell);
col_means
});
for col in col_means.iter_mut() {
*col /= col_len as f64;
}
col_means
}
fn main() {
let mat: Vec<Vec<f64>> = vec![
vec![5.0, 9.0, 4.0],
vec![8.0, 8.0, 2.0],
vec![4.0, 5.0, 3.0],
];
let col_means = col_means(&mat);
println!("{:?}", col_means);
// Outputs `[5.666666666666667, 7.333333333333333, 3.0]`
}
或者,您可以避免使用内部的Vec,然后使用chunks(),从而去除一层间接性。
fn col_means(mat: &[f64], col_len: usize) -> Vec<f64> {
let mut col_means = mat
.chunks(col_len)
.fold(vec![0.0; col_len], |mut col_means, row| {
row.iter()
.enumerate()
.for_each(|(i, cell)| col_means[i] += cell);
col_means
});
for col in col_means.iter_mut() {
*col /= col_len as f64;
}
col_means
}
fn main() {
let mat: Vec<f64> = vec![5.0, 9.0, 4.0,
8.0, 8.0, 2.0,
4.0, 5.0, 3.0];
let col_means = col_means(&mat, 3);
println!("{:?}", col_means);
// Outputs `[5.666666666666667, 7.333333333333333, 3.0]`
}
旧答案
假设内部Vec 是一行。然后您可以使用iter()、sum() 和collect() 组合成Vec。
let mat: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![2, 3, 4], vec![3, 4, 5]];
let row_means = mat
.iter()
.map(|row| row.iter().sum::<i32>() / (row.len() as i32))
.collect::<Vec<_>>();
println!("{:?}", row_means);
// Outputs `[2, 3, 4]`
或者,您可以避免使用内部的Vec,然后使用chunks(),从而去除一层间接性。
let mat: Vec<i32> = vec![1, 2, 3, 2, 3, 4, 3, 4, 5];
let row_len = 3;
let row_means = mat
.chunks(row_len as usize)
.map(|row| row.iter().sum::<i32>() / row_len)
.collect::<Vec<_>>();
println!("{:?}", row_means);
// Outputs `[2, 3, 4]`
然后您可以将实现抽象并隐藏到可重用的struct Mat。
struct Mat(usize, Vec<i32>);
impl Mat {
fn row_means(&self) -> Vec<i32> {
let row_len = self.row_len();
self.1
.chunks(row_len)
.map(|row| row.iter().sum::<i32>() / (row_len as i32))
.collect()
}
fn cell(&self, row: usize, col: usize) -> i32 {
self.1[col + row * self.row_len()]
}
fn row_len(&self) -> usize {
self.0
}
fn col_len(&self) -> usize {
self.1.len() / self.row_len()
}
}
fn main() {
let mat = Mat(3, vec![1, 2, 3,
2, 3, 4,
3, 4, 5]);
println!("{:?}", mat.row_means());
// Outputs `[2, 3, 4]`
}