I'm on my 12th hour of coding today (I know you've been there ) and I'm seeking assistance to solve the following problem. The snippet below works and produces the desired result but, my God is it ugly:
fn main() {
let data = vec![
vec![0.05, 0.12, 0.8],
vec![0.18, 0.22, 1.9],
vec![0.31, 0.35, 3.2],
vec![0.42, 0.38, 4.6],
vec![0.5, 0.49, 5.0]
];
// I only want to retain the 0th and 2nd elements from each
// of the internal vecs
let idxs: Vec<usize> = vec![0,2];
let data: Vec<Vec<f64>> = data.iter()
.map(|el| {
el.iter()
.enumerate()
.filter(|(i, _)| idxs.contains(i))
.map(|e| e.1)
.cloned()
.collect()
})
.collect();
println!("{:#?}", data);
}
What's a better way to do this (in terms of performance/code cleanliness)?
This is very nice, thank you. Is there a way to make it dynamic? In my program, the idxs vec is passed in by the user. How would I go from vec![0,2,3], for example, to [a,_,b,c] and then to Some(vec![a,b,c])?
This is really nice too. I'll try to benchmark the two approaches later to see what's more performant. Any ideas though as to which will perform better?
I agree, that's the best one Not sure if youre aware, though, but our solutions don't quite behave the same as yours, because they panic if an index a user gave was invalid. You'd need to handle that, e.g. like this:
let data: Vec<Vec<f64>> = data.iter()
.map(|inner| idxs.iter().filter_map(|&i| inner.get(i)).collect())
.collect();
Tough to tell, in my solution you could give a capacity to the vecs to allocate exactly right. Not sure if that can work with the functional solution (the user-vec is dynamic, right). But that might behave better wrt bounds checks.
Truth be told though, measure if you're interested, but ignore it unless a benchmark tells you this is relevant. It's really a micro-optimization, go for readability first.