Initializing array of struct with literals

I have:

using Luxor
pl = [Point(0,0), Point(1,1), Point(2,0), Point(3,0), Point(4,0)]

where Luxor.Point is defined as:

struct Point
   x::Float64
   y::Float64
end

Is there a way to initialize pl without repeating the constructor call for each element? Something along the lines of:

pl = Array{Point, 1}[(0,0), (1,1), (2,0), (3,0), (4,0)]

Yes, use an array comprehension:

pl = [Point(i, j) for (i, j) in ((0,0), (1, 1), (2, 0), (3, 0), (4, 0))]
5 Likes

Thank you. This is much less tedious.

2 Likes

Does the Luxor.Point constructor allow for taking in a Tuple? If so you could just do

Point.(points)

where points is a vector of tuples each of length 2.

3 Likes

Otherwise, this will also work:

((t,) -> Point(t[1], t[2])).([(0,0), (1, 1), (2, 0), (3, 0), (4, 0)])

But it remembers me of:

3 Likes

No, it doesn’t:

julia> pl = Point.((0,0), (1,1), (2,0), (3,0), (4,0))
ERROR: MethodError: no method matching Point(::Int64, ::Int64, ::Int64, ::Int64, ::Int64)

It also does something quite unexpected for me:

julia> pl = Point.((0,0), (1,1))
(Point(0.0, 1.0), Point(0.0, 1.0))

That’s just broadcasting; you could get what you want with it: Point.(0:4, 0)

3 Likes

I defined:

Point((x, y)::Tuple{Real, Real}) = Point(x, y)

and now I can write:

pl = Point.([(0, 0), (1, 1), (2, 0), (3, 1), (4, 0)])
1 Like