Reputation: 401
Beginner question:
How to make an Array of objects from a Struct in Crystal? Or how to make an array of objects in Crystal? I am trying to emulate the go code.
struct Book
def initialize(
@Id : Int32,
@Title : String,
@Author : String,
@Desc : String
)
end
end
books = [] of Int32 | String <--- This is wrong
book1 = Book.new(1, "Hello", "Me", "This is a test.")
GO CODE:
type Book struct {
Id int `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
Desc string `json:"desc"`
}
var Books = []models.Book{
{
Id: 1,
Title: "Golang",
Author: "Gopher",
Desc: "A book for Go",
},
}
Changing to a class allows me to return a new object. Which I am sure is the wrong way to make a new object in Crystal? I can then add objects to the array.
class Book
def initialize(id : Int32, title : String, author : String, desc : String)
@id = id
@title = title
@author = author
@desc = desc
end
def object
{
@id,
@title,
@author,
@desc
}
end
end
books = [] of Book <--- HOW TO SET ARRAY OF OBJECTS ON THE TYPE?
book1 = Book.new(1, "Hello", "Me", "This is a test.")
puts book1.object
books << book1.object
puts books
Upvotes: 1
Views: 375
Reputation: 401
It seems really what I wanted, and what was not the same as the struct version in go was an Array of Hashes, which in turn is an Array of Objects, as everything is an Object in Crystal?*.
hash = [] of Hash(Int32, String) # Array of Hashes
hash0 = {0 => "Jackson0"}
hash1 = {1 => "Jackson1"}
hash2 = {2 => "Jackson2"}
hash3 = {3 => "Jackson3"}
#Append the hashes to the array
hash << hash0
hash << hash1
hash << hash2
hash << hash3
OR
(0..3).each do |i|
hash << {i => "Jackson#{i}"}
end
RESULT : [{0 => "Jackson0"}, {1 => "Jackson1"}, {2 => "Jackson2"}, {3 => "Jackson3"}]
# Display them as JSON
get "/" do
hash.to_json
end
RESULT : [{"0":"Jackson0"},{"1":"Jackson1"},{"2":"Jackson2"},{"3":"Jackson3"}]
Which in turn can be queried using hash[0][1]
RESULT : {"1": "Jackson1"}
Upvotes: 1
Reputation: 198314
You can write
books = [] of Book
books << book1
or you can simply do this, and let Crystal recognise the type:
books = [book1]
The closest to the original is
books = [
Book.new(1, "Hello", "Me", "This is a test.")
]
EDIT: If you need JSON, you need to implement it, as described in the documentation. The easiest is to include JSON::Serializable
:
require "json"
module TestBookJSON
struct Book
include JSON::Serializable # <-- this
def initialize(
@Id : Int32,
@Title : String,
@Author : String,
@Desc : String
)
end
end
books = [] of Book
book1 = Book.new(1, "Hello", "Me", "This is a test.")
books << book1
puts books.to_json
# => [{"Id":1,"Title":"Hello","Author":"Me","Desc":"This is a test."}]
end
Upvotes: 1