Given the following generator:
xs = range(0, stop=1, length=10)
ys = range(0, stop=1, length=10)
((x, y) for (x, y) in Iterators.product(xs, ys))
How to "vec" it so that the result is 1-dimensional? I am currently relying on IterTools.ivec
, but would like to drop this dependency.
Is there an easy workaround that doesn't rely on defining a whole new IVec
struct?
I’m pretty sure you can just put an if true
at the end of the generator to turn it into a filtered generator and then it will lose all shape information
Yes but it also loses its length information (making the collect significantly slower). You can call collect, then call vec on it.
In my use case I actually managed to do a simpler trick:
https://github.com/JuliaGeometry/Meshes.jl/commit/16b340e5123dccbac98c742f142a987eb6b93cfd#
Because I have the number of iterators a priori, I can manually add two "for" keywords to flatten the vector. This is different than a single "for" with commas.
Júlio Hoffimann has marked this topic as resolved.
julia> ((x, y) for (x, y) in Iterators.product(xs, ys)) |> collect
10×10 Matrix{Tuple{Float64, Float64}}:
(0.0, 0.0) (0.0, 0.111111) (0.0, 0.222222) (0.0, 0.333333) … (0.0, 0.666667) (0.0, 0.777778) (0.0, 0.888889) (0.0, 1.0)
(0.111111, 0.0) (0.111111, 0.111111) (0.111111, 0.222222) (0.111111, 0.333333) (0.111111, 0.666667) (0.111111, 0.777778) (0.111111, 0.888889) (0.111111, 1.0)
(0.222222, 0.0) (0.222222, 0.111111) (0.222222, 0.222222) (0.222222, 0.333333) (0.222222, 0.666667) (0.222222, 0.777778) (0.222222, 0.888889) (0.222222, 1.0)
(0.333333, 0.0) (0.333333, 0.111111) (0.333333, 0.222222) (0.333333, 0.333333) (0.333333, 0.666667) (0.333333, 0.777778) (0.333333, 0.888889) (0.333333, 1.0)
(0.444444, 0.0) (0.444444, 0.111111) (0.444444, 0.222222) (0.444444, 0.333333) (0.444444, 0.666667) (0.444444, 0.777778) (0.444444, 0.888889) (0.444444, 1.0)
(0.555556, 0.0) (0.555556, 0.111111) (0.555556, 0.222222) (0.555556, 0.333333) … (0.555556, 0.666667) (0.555556, 0.777778) (0.555556, 0.888889) (0.555556, 1.0)
(0.666667, 0.0) (0.666667, 0.111111) (0.666667, 0.222222) (0.666667, 0.333333) (0.666667, 0.666667) (0.666667, 0.777778) (0.666667, 0.888889) (0.666667, 1.0)
(0.777778, 0.0) (0.777778, 0.111111) (0.777778, 0.222222) (0.777778, 0.333333) (0.777778, 0.666667) (0.777778, 0.777778) (0.777778, 0.888889) (0.777778, 1.0)
(0.888889, 0.0) (0.888889, 0.111111) (0.888889, 0.222222) (0.888889, 0.333333) (0.888889, 0.666667) (0.888889, 0.777778) (0.888889, 0.888889) (0.888889, 1.0)
(1.0, 0.0) (1.0, 0.111111) (1.0, 0.222222) (1.0, 0.333333) (1.0, 0.666667) (1.0, 0.777778) (1.0, 0.888889) (1.0, 1.0)
julia> ((x, y) for y in ys for x in xs) |> collect
100-element Vector{Tuple{Float64, Float64}}:
(0.0, 0.0)
(0.1111111111111111, 0.0)
(0.2222222222222222, 0.0)
(0.3333333333333333, 0.0)
(0.4444444444444444, 0.0)
(0.5555555555555556, 0.0)
⋮
(0.4444444444444444, 1.0)
(0.5555555555555556, 1.0)
(0.6666666666666666, 1.0)
(0.7777777777777778, 1.0)
(0.8888888888888888, 1.0)
(1.0, 1.0)
Out of curiosity does calling Vector on it work? That actually sounds like the nicest way of solving it in general
You mean replacing collect
with Vector
@Jakob Nybo Nissen?
I think we need to collect the generator before feeding it to the Vector
constructor.
Yeah... I think the Vector constructor ought to take arbitrary iterables
Last updated: Nov 06 2024 at 04:40 UTC