Go gota Dataframe not loading struct, requires []struct - go

I am reading a file with each row containing two words separated by a space. I scan and split each line to two words (strings) and store them in the MyEntity struct (in items). The words are then added to items.
type Entity struct {
Name string
Entity string
}
type MyEntity struct {
Entities []Entity
}
func (entity *MyEntity) AddEntity(item Entity) []Entity {
entity.Entities = append(entity.Entities, item)
return entity.Entities
}
...
items := MyEntity{}
// loop here over the rows - name is first word, entity is second word
item := Entity{
name, entity,
}
items.AddEntity(item)
...
Should items not be a []struct here? I am using the gota package (https://github.com/go-gota/gota) to create a DataFrame from items but using dataframe.LoadStructs(items) fails because items is a struct and it must be a []struct.
I am fairly new to Go, so what am I missing here?

Load the data frame from the slice of entities:
df := dataframe.LoadStructs(items.Entities)

Related

update a map whose value is an array of object but get error

I just started learning Golang today. So, I suppose this question is a basic one howerver I tried what I can try, but get error.
So, I have defined a Student struct type:
type Student struct {
firstname string `json:"first_name"`
id int `json:"id"`
}
I want to have a map data structure, in which the map's key represent "class id" & the value of each key in this map is an array of Student. This is what I have tried:
var studentsMap = make(map[int][]Student)
func registerStudent(classId int, studentName string, studentId int) {
var studentsInClass = studentsMap[classId]
if studentsInClass == nil {
studentsInClass = []Student{}
}
// append the new student to the studentsInClass array
var updatedStudentsArr = append(studentsInClass, Student{studentName, studentId})
// update the map for this class id with updated array of students
// Compiler ERROR: Cannot use 'updatedStudentsArr' (type []Student) as the type Student
studentsMap[classId] = updatedStudentsArr
}
As you see in my comment in the code, when I try to update the studentsMap with the new array, I get compiler error Cannot use 'updatedStudentsArr' (type []Student) as the type Student. Why is that? My guess is that I defined wrongly the studentsMap map type, but how to fix?
The code you posted seems to be working fine, as pointed out by #nipuna in the comments.
As a small note, when you test for a key,value existence in go you get two values, the latter being a boolean. You can thus use the following to test whether studentsMap[classId] exists
studentsInClass, ok := studentsMap[classId]
if !ok {
studentsInClass = []Student{}
}
Regarding your second question related to #Volker's comment, you can read more about exporting struct fields in the following answers.
If you are using an IDE, it might be warning you about it (e.g. in VSCode I get struct field firstname has json tag but is not exported).
https://stackoverflow.com/a/50320595/5621318
https://stackoverflow.com/a/11129474/5621318
https://stackoverflow.com/a/25595269/5621318

Decode spanner row fields to nested structs golang

I have two structs
type Row struct{
ID string
Status string
details Details
}
type Details struct{
SessionID string
Location string
Project string
}
And I get data like this
Select a.ID, a.Status, b.SessionID, b.Location, b.Project from table1 as a left join table2 as b on a.ID == b.SessionID
Now, to get all the select info in a row I need to change the struct and add the fields in it instead of a struct(Details) which is essentially duplicating fields in Row and Details (which I need for other purpose as well).
type Row struct{
ID string
Status string
SessionID string
Location string
Project string
}
r := Row{}
spanner.row.ToStruct(&r) // this works
but is there a simplified way to get the data without having to duplicate the fields in the struct or specifying each field in spanner.row.Column? I read that spanner.row.ToStruct does not support destination struct to have a struct as field as that's not a supported column type, but what's a better workaround?
Thanks!
I have not worked on the google cloud scanner directly but from the Go language point of view, How about embedding the Structs?
i.e.:
type Row struct{
ID string
Status string
Details
}
type Details struct{
SessionID string
Location string
Project string
}
r := Row{}
spanner.row.ToStruct(&r)

How to use reflection to set nested struct field values

I'm using Go to create a nested struct and populate it. I have a custom field in the struct that I need to set myself, but it's a type used in a field of the outer struct. For example:
type Case struct {
CaseID string `json:"caseID"`
CaseStatus string `json:"caseStatus"`
Kit_Details []Kit_Details `json:"kit_Details"`
}
type Kit_Details struct {
KitID string `json:"kitID"`
KitStatus string `json:"kitStatus"`
}
I have created a nested struct. I want to update KitStatus fields using Case struct in my program.Means if I access Case struct from that how can i move to Kit_Details struct and update the field of a structure.
Can somebody help me how to loop through the fields of Case struct using FieldByName("KitStatus") and using SetString("New value") to update the value of that field.
You can use like this:
v := reflect.ValueOf(test)
fmt.Println("Value of test before update", v)
v.FieldByName("Kit_Details").Index(0).FieldByName("KitStatus").SetString("abcdsdf")
You can use a loop to traverse all the elements and update them using Index().
Go play ground link

Unable to update jsonb (ie subarray) column

I am just getting my feet wet with go-pg, and having some issues utilizing the JSONB capabilities of PostgreSQL DB.
I have defined my model structs as:
type Chemical struct {
Id int
ChemicalName string
ListingDetails []ListingDetail `sql:",array"`
ParentChemical *Chemical `pg:"fk_parent_chemical_id"`
ParentChemicalId int
}
type ListingDetail struct {
TypeOfToxicity string
ListingMechanism string
CasNo string
ListedDate time.Time
SafeHarborInfo string
}
In the Chemical struct - by using the tag sql:",array" on the ListingDetails field - my understanding is this should get mapped to a jsonb column in the destination table. Using go-pg's CreateTable - a chemicals table gets created with a listing_details jsonb column - so all is good in that regards.
However, I cant seem to update this field (in the db) successfully. When I initially create a chemical record in teh database - there are no ListingInfos - I go back up update them at a later time. Below is a snippet showing how I do that.
detail := models.ListingDetail{}
detail.TypeOfToxicity = strings.TrimSpace(row[1])
detail.ListingMechanism = strings.TrimSpace(row[2])
detail.CasNo = strings.TrimSpace(row[3])
detail.SafeHarborInfo = strings.TrimSpace(row[5])
chemical.ListingDetails = append(chemical.ListingDetails, detail)
err = configuration.Database.Update(&chemical)
if err != nil {
panic(err)
}
But I always get error message shown below. What am I doing wrong??
panic: ERROR #22P02 malformed array literal: "{{"TypeOfToxicity":"cancer","ListingMechanism":"AB","CasNo":"26148-68-5","ListedDate":"1990-01-01T00:00:00Z","SafeHarborInfo":"2"}}"

Golang Map with array of values

What does this statement mean in Go:
Student.bookMap=map[string][]*model.Books{}
Where Student is:
type Student struct{
bookMap map[string][]*model.Books
}
and we have a model package
package model
type Books struct {
bookName string `db:"Name"`
bookAuthor string `db:"Author"`
}
That statement is initializing the map Student.bookMap to an empty map (which has the following structure: key -> string, value -> slice of pointers of model.Books).
It means the member bookMap of a struct Student contains a map which takes a string as a key, and an array (slice) of pointers to instances of model.Books as value.

Resources