I have the following code which collects gaps in a number sequence into a separate vec
.
There will never be a case, iterating over a Vec<i32>
where .windows(2)
will yield a window with None
values. So I want to simplify things by transforming each window into a Gap
with first and last i32
values wherever the gap between 2 numbers is > 1. So a transform -> filter -> result
kind of pipeline.
My version works, but seems imperative and long-winded. I keep thinking I should be able to use .from_fn()
, .filter()
and .collect()
to generate the gap
vector without a for
loop. How would I go about this?
#[derive(Debug)]
struct Gap {
first: i32,
last: i32,
}
fn main() {
let original_numbers = vec![1, 3, 4, 7, 8, 10, 11, 13, 6, 19, 20, 21];
let mut seq = original_numbers.clone();
seq.sort();
let windows = seq.windows(2);
let mut gaps: Vec<Gap> = Vec::new();
for gap_window in windows {
let g = Gap {
first: if let Some(num) = gap_window.first() { *num + 1 } else { 0 },
last: if let Some(num) = gap_window.last() { *num - 1 } else { 0 },
};
if g.last - g.first >= 0 {
gaps.push(g)
}
}
for gap in gaps {
println!("{:?}", gap)
};
}
Output:
Gap { first: 2, last: 2 }
Gap { first: 5, last: 5 }
Gap { first: 9, last: 9 }
Gap { first: 12, last: 12 }
Gap { first: 14, last: 18 }