With struct Var
defined like this:
pub struct Var {
val: i32,
}
I hope to add up all val
from an array of Var
s:
pub struct Var {
val: i32,
}
fn main() {
let var0 = Var { val: 0 };
let var1 = Var { val: 1 };
let array = [var0, var1];
let sum = array.into_iter().reduce(|x, y| Var { val: x.val + y.val });
}
The code looks redundant to me as for every addition in reduce
, a new Var
was created. I hope to avoid such waste by adding only val
yet it is impossible:
let sum = array.into_iter().reduce(|x, y| x.val + y.val);
expected struct
Var
, foundi32
The other way to fix it would be to fetch val
from all var
and then sum them up, which doesn't look too smart either:
let vals: Vec<i32> = array.into_iter().map(|var| var.val).collect();
let sum = vals.into_iter().reduce(|x, y| x + y);
Is there an elegant and efficient way to sum up all member variables from an array of struct?
You can chain iterators without needing to collect
intermediate results:
let sum = array.into_iter().map (|var| var.val).reduce(|x, y| x + y);
Or better, you can use sum
instead of reduce
, and use iter
instead of into_iter
so that you won't destroy the original array:
let sum = array.iter().map (|var| var.val).sum::<i32>();
Another notable option is to use fold
to combine the effects of map
and sum
in a single call:
let sum = array.fold (0, |v, s| s + v.val);
Note that reduce
returns None
for an empty array and Some (sum)
for a non-empty array, the other solutions return 0
for an empty array and the bare sum otherwise.