These suggested fixes look worse to me. In the first one, the "wrong" function was quite clear (special case 0, special case 1, general case) while the second one allocated memory. I'd call that a code smell!
result = input.map.with_index do |_, i|
input.better_fetch(i-1, 0) + input.better_fetch(i+1, 0)
end.to_a input.get(i.wrapping_sub(1)).unwrap_or(0) + input.get(i+1).unwrap_or(0)
This also technically won't work right if the slice has usize::MAX elements, but that's rather unlikely.This is one area where Swift's choice of using signed Int for most things actually works quite well. The equivalent Swift code would be something like
(input[safe: i-1] ?? 0) + (input[safe: i+1] ?? 0)
though unfortunately Swift doesn't ship with Array.subscript(safe:) so you have to write that yourself.Not in release mode.
result = input.each_cons(3).map do |left, _, right|
left + right
end
This maps over consecutive three-tuples in `input` and returns empty array for `len(input) < 3`.Edit: nevermind, boundary conditions are still special cases.
Relatedly, in image and video processing the (literal) "edge cases" are sometimes handled by allocating the buffer slightly larger in the first place, so that filtering operations (which are very similar to that example) don't run off the edge. Maybe the real lesson here is "think ahead"?