I'm trying to build a few primitive objects to store a graph:
Vertex = Struct.new(:parent, :rank)
Graph = Struct.new(:vertexes, :edges)
Edge = Struct.new(:weight, :endpoints)
The idea here is that :endpoints
(and :parent
) are Vertexes, and, naturally, Graph
stores lists of Vertexes and Edges. I tried to set this up, and I ran into trouble:
[47] pry(main)> t_graph = Graph.new()
=> #<struct Graph vertexes=nil, edges=nil>
[48] pry(main)> t_graph[:vertexes] = Array.new(Vertex.new())
TypeError: can't convert Vertex into Integer
from (pry):48:in `initialize'
On the other hand, this works:
[49] pry(main)> t_graph[:vertexes] = [Vertex.new(), Vertex.new()]
=> [#<struct Vertex parent=nil, rank=nil>,
#<struct Vertex parent=nil, rank=nil>]
What's the efficient way to generate a mass of empty Vertexes in a Graph (or any such relation) for testing?
I disagree a bit with Array.new not being useful here. Find below my use case which solves the posters problem, even though this has been displayed but not well explained above:
As displayed on line
[35]
you can callArray.new
supplying the number of elements you want in the array in this case 2 and what the elements should be in this caseVertex.new
James Edward Gray II did a talk on Avdi Grimm's podcast(no advert intent here) that clearly explains a very similar example
Array.new
is not the standard way to initialize an array with a value. If you want to create an array with a Vertex instance, useAs described in the documentation,
Array.new
takes either an array or a Fixnum size of the array.One more thing: you can omit parenthesis when there are no args.
instead of
Keep in mind you can add methods to Structs.
One way to simply populate a list of Vertexes is to use
.times
, which seems kind of clumsy, but creates a list (I added an:id
value):This creates different objects.
To add these en masse to a Graph, Simone's method can be used to add the list of Vertexes to the Graph:
It looks like I need to build a constructor method that builds the Graph from an adjacency list and weight list; I don't see a simple way to do this in one big step.