Suppose I have:
a = [1;2;3]
b = [4;5;6]
c = nothing
d = [7;8;9]
In my code, somtimes c
will have values, other times it will not. I can guarantee that the type of all variables is the same. What I want is then a function to concatenate the vectors with values, so that I get:
[1;2;3;4;5;6;7;8;9]
Which is exactly what I want, since c
is nothing and I don’t want it to be in there.
Is there an elegant way to achieve this?
reduce(vcat, filter(!isnothing, (a,b,c,d)))
?
Thanks! I was missing reduce
.
Base.vcat(n::Nothing,x)=x
Base.vcat(x,n::Nothing)=x
reduce(vcat, (a,b,c,d))
Nice, but instead of adding methods to vcat
(type piracy) you could also define a wrapper changing the operator used in reduce to ignore nothing:
struct SkipNothing{F}
op::F
end
(obj::SkipNothing)(x, y) = obj.op(x, y)
(obj::SkipNothing)(::Nothing, x) = x
(obj::SkipNothing)(x, ::Nothing) = x
reduce(SkipNothing(vcat), (a, b, c, d))
Transforming reducing functions in this fashion is precisely the idea behind Transducers
:
using Transducers
foldxt(vcat, NotA(Nothing), (a, b, c, d)) # Essentially the same as above, but threaded
(a, b, c, d) |> NotA(Nothing) |> Cat() |> collect
2 Likes
I expected that there was something wrong.
But I expected, as I did, that I would learn something anyway.
I propose another
mapreduce(x->something(x,[]),vcat, (a,b,c,d))