Suppose I have the following v
and w
as follows:
julia> v = [1:3, 4:6, 1:2, 3:6, 1:6, 1:6];
julia> w = [1:3, 4:6, 1:6, 1:6, 1:6, 1:4, 5:6, 1:6];
and I want a function to return the minimum and the maximum which would cover all the values in the ranges, i.e. (1,6) in this case.
Currently, I've tried:
flatextrema(q) =
foldl((r,b)->
(min(first(r),first(b)),max(last(r),last(b))), q;
init=(first(first(q)),last(first(q))))
flatextrema(q,r...) =
flatextrema((flatextrema(q),flatextrema.(r)...))
which gives me:
julia> flatextrema(v,w)
(1, 6)
Is there some nicer/shorter/faster way?
This version of flatextrema
takes quite a wide range of possible parameters and returns a tuple.
Another example would be:
julia> flatextrema([1:3,2:4,3:5],[-3:3,1:4],10)
(-3, 10)
The idea is to get a minimum and a maximum which would include all scalars in the parameters.
You like any of these?
v = [1:3, 4:6, 1:2, 3:6, 1:6, 1:6]
w = [1:3, 4:6, 1:6, 1:6, 1:6, 1:4, 5:6, 1:6]
function flatextrema1(vs...)
all_ranges = Iterators.flatten(vs)
minimum(minimum.(all_ranges)), maximum(maximum.(all_ranges))
end
function flatextrema2(vs...)
all_extrema = extrema.(Iterators.flatten(vs))
minimum(first.(all_extrema)), maximum(last.(all_extrema))
end
function flatextrema3(vs...)
all_extrema = extrema.(Iterators.flatten(vs))
extrema(Iterators.flatten(all_extrema))
end
# flatextrema = flatextrema1
# flatextrema = flatextrema2
flatextrema = flatextrema3
flatextrema(v, w) # (1, 6)
flatextrema(v, w, 10) # (1, 10)
May be some cool way to do this with JuliaFolds/Transducers.jl - I need to check that package out properly.
Edit (after benchmark comment):
Ok here's a faster version
function flatextrema4(vs...)
mn,mx = typemax(Int), typemin(Int)
for cc in vs, c in cc
cmn, cmx = extrema(c)
mn, mx = min(mn, cmn), max(mx, cmx)
end
return mn, mx
end
Edit 2 (post accept): Bonus Transducer version (pretty fast and concise)
using Transducers
function flatextrema5(vs...)
foldxl(ProductRF(min, max), vs |> Cat() |> Map(extrema))
end
I will note that while these solutions handle the amount of nesting in your examples, none of them are generic enough to handle arbitrary nesting. To do that you'd need a more generic, and likely slower, flattening step.