How to process array items given in YAML to associate with a struct in Go? - arrays

I have not found a way to allocate values defined in an array within a YAML file field to the fields of a struct in Go. I am already unmarshalling the whole file to a defined struct, but I would like to go deeper.
The YAML file is a hardcoded file.
YAML File
- id : [apples,bananas]
fruits: true
vegetables: false
- id : [apples,onions]
fruits: true
vegetables: true
Go structs
type Basket struct {
ID RawID `yaml:"id"`
Content BasketContent
}
type RawID struct {
Apples bool `yaml:"apples"`
Bananas bool `yaml:"bananas"`
Onions bool `yaml:"onions"`
}
type BasketContent struct {
Fruits boolean `yaml:"fruits"`
Vegetables boolean `yaml:"vegetables"`
}
I am expecting to identify which elements are located in the id field, to later hash them into a value.

You could try the following package that has definitions of yaml to structs
https://github.com/go-yaml/yaml
This includes documentation on how to handle arrays.
Edit 1: Including relevant code snippet
var data = `
a: Easy!
b:
c: 2
d: [3, 4]
`
// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
A string
B struct {
RenamedC int `yaml:"c"`
D []int `yaml:",flow"`
}
}

Related

To create map of array of map in golang

I want to create a json in golang for which I need to first create map of the following:
{"inputs": [{"data": {"image": {"url": "SOME_URL"}}}]}
how to create this map on golang. (for now even hardcoded will also work for me)
In a struct:
type SomeData struct {
Inputs []struct {
Data struct {
Image struct {
URL string `json:"url"`
} `json:"image"`
} `json:"data"`
} `json:"inputs"`
}
But if we wanted to be able to add things individually, AND be more idiomatic, we would do it like this:
type Image struct {
URL string `json:"url"`
}
type Data struct {
Image Image `json:"image"`
}
type Input struct {
Data Data `json:"data"`
}
type SomeData struct {
Inputs []Input `json:"inputs"`
}
Then, of course, we could always just use a map:
someData := map[interface{}]interface{}{}
It really just depends on which route you'd like to go. I suggest the second one as it gives you better fine-grained tooling without any pesky dirty tricks or code-clutter.
Hope this helps!
neededMap := make(map[string][]map[string]map[string]map[string]string)

Golang nested struct slice - Error index out of range

Playground
I'm trying to store a string into a slice field inside a struct. This is for collecting data and create a Json to post via to an API.
package main
type response1 struct {
Identifier string `json:"identifier"`
Family string `json:"family"`
Values struct {
Logo []struct {
Data string `json:"data"`
Scope string `json:"scope"`
} `json:"logo"`
}
}
func main() {
res2D := &response1{
Identifier: "1234567",
Family: "example",
}
res2D.Values.Logo[0].Data = "test"
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))
}
Error
And the error I got:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmp/sandbox507443306/main.go:22 +0xe0
You do not have to make the slice with appropriate size before hand. You can use append. What you are trying to do in your example is assign a slice "[0]" that has not been created yet, which is why you are getting your error. Use append and change your line
res2D.Values.Logo[0].Data = "test"
to
res2D.Values.Logo = append(res2D.Values.Logo,struct {Data string "json:\"data\"" }{Data: "test"})
and that will append the literal struct into your array. Now by looking at your code I am assuming you doing this as a test to explore the language so I wont go into detail on how to better write this without knowing what you are actually using it for.

Parse embedded Struct form values in GoLang

I have a struct that includes an array of another struct, eg
type Struct1 struct {
Value string
Items []Struct2
}
type Struct2 struct {
Value string
}
I am using gorilla schema to decode my Form values into Struct 1.
The values for the embedded struct, Struct 2, are not coming through.
When I look at the logs for the FormValue("Struct2") it returns '[Object object], [Object object]'
Any help would be greatly appreciated
EDIT
An example of the structure of the form,
Using AngularJS,
var data = $scope.struct1;
$http({
method: 'POST',
url:url,
data : data,
headers : {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
})
.then(function successCallback(response) {
console.log(response);
}, function errorCallback(response) {
});
It's possible that you don't have the right struct design for your HTML form. You might want to post your input and/or your HTML form design.
gorilla/schema's decode expects the values input to be passed as a variable of type map[string][]string, as you can see both from the example in the documentation and from the test files in the package. Here's a simple complete script that just wraps the example from the documentation and prints the result:
package main
import(
"fmt"
"github.com/gorilla/schema"
)
type Person struct {
Name string
Phone string
}
func main() {
values := map[string][]string{
"Name": {"John"},
"Phone": {"999-999-999"},
}
person := new(Person)
decoder := schema.NewDecoder()
decoder.Decode(person, values)
fmt.Printf("Person: %v\n", person)
}
That outputs Person: &{John 999-999-999}.
That is the correct form for a map literal of type map[string][]string, as you can demonstrate by performing a declaration followed by an assignment and running it without error:
var values map[string][]string
values = map[string][]string{
"Name": {"John"},
"Phone": {"999-999-999"},
}
Now map[string][]string doesn't obviously support all the types that gorilla/schema supports, such as the type in your question: slices of structs. But the HTML form is processed such that a translation makes sense: it keeps appending indices and field names with dot separators to create the desired structure. So for the types you posted in your question, I wrote this script to decode values into the structs:
package main
import(
"fmt"
"github.com/gorilla/schema"
)
type Struct1 struct {
Value string
Items []Struct2
}
type Struct2 struct {
Value string
}
func main() {
values := map[string][]string{
"Value": {"the thing with the items"},
"Items.0.Value": {"a"},
"Items.1.Value": {"b"},
"Items.2.Value": {"c"},
}
s1 := new(Struct1)
decoder := schema.NewDecoder()
decoder.Decode(s1, values)
fmt.Printf("S1: %v\n", s1)
}
Running that outputs:
S1: &{the thing with the items [{a} {b} {c}]}
That demonstrates that decode can populate your struct design without error, if its input matches that design.
So you might try to verify that your input matches that scheme -- that it has those array-like indices and field names with the dot separator in a way that conforms to your struct design. And if it does not, that indicates that your struct design needs to be updated to fit the format of your input.
You can see examples of decode working on this type of structure in the decode_test.go file in the gorilla/schema package, such as these lines:
type Foo struct {
F01 int
F02 Bar
Bif []Baz
}
type Bar struct {
F01 string
F02 string
F03 string
F14 string
S05 string
Str string
}
type Baz struct {
F99 []string
}
func TestSimpleExample(t *testing.T) {
data := map[string][]string{
"F01": {"1"},
"F02.F01": {"S1"},
"F02.F02": {"S2"},
"F02.F03": {"S3"},
"F02.F14": {"S4"},
"F02.S05": {"S5"},
"F02.Str": {"Str"},
"Bif.0.F99": {"A", "B", "C"},
}
The Foo struct has a field named Bif of type []Baz. Baz is a struct -- so we have a slice of structs type, like in your question. Baz has a field named F99. You can see that the input is referenced with the string value "Bif.0.F99".
Use this and other examples in the test file as your guide.

How can we initialize an array of type struct (which stores the json output) within a struct in golang

I need to initialize the following data structure which will store a json. The Attack_plans will hold multiple plans and if I loop through the GeneratePlan struct, I need all the plans that were stored.
type GeneratePlan struct {
Mode string `json:"mode"`
Name string `json:"name"`
Schema string `json:"schema"`
Version string `json:"version"`
Attack_plans []struct {
Attack_plan *Attack_plan `json:"attack-plan"`
} `json:"attack-plans"`
}
type Attack_plan struct {
Attack_resources []struct {
Attack_resource *Attack_resource `json:"attack-resource"`
} `json:"attack-resources"`
}
Can anyone please suggest something? If the data structure needs to be simplified before initializing it, then please suggest that as well. I am very new to golang so please ignore the best practices to follow. Any help is appreciated. Thanks!
why don't u just json.marshal your object to a json string, you can got answer
generatePlan := GeneratePlan{
Mode: "mode",
Name: "name",
Schema: "sachema",
Version: "version",
Attack_plans: []struct {
Attack_plan *Attack_plan `json:"attack-plan"`
}{
{Attack_plan: &Attack_plan{[]struct {
Attack_resource *Attack_resource `json:"attack-resource"`
}{
{Attack_resource: new(Attack_resource)},
{Attack_resource: new(Attack_resource)},
}}},
{Attack_plan: &Attack_plan{[]struct {
Attack_resource *Attack_resource `json:"attack-resource"`
}{
{Attack_resource: new(Attack_resource)},
{Attack_resource: new(Attack_resource)},
}}},
},
}
I found the solution! This simplifies the above data structure!
type GeneratePlan struct{
Mode string `json:"mode"`
Name string `json:"name"`
Schema string `json:"schema"`
Version string `json:"version"`
Attack_plans []struct1 `json:"attack-plans"`
}
type struct1 struct {
Attack_plan Attack_plan `json:"attack-plan"`
}
type Attack_plan struct{
Attack_resouces []struct2 `json:"attack-resources"`
}
type struct2 struct {
Attack_resource Attack_resource `json:"attack-resource"`
}

Swift. Sort array of struct

I need to order an array of struct.
I've try:
let aRes = self.aSoundTracks_Filtered.sort{ $0.st < $1.st }
provide error: Cannot invoke 'sort' with an argument list of type '((_, _) -> _)'
also try this:
let hasPrefixAndSuffixw = self.aSoundTracks_Filtered.sort( $0.st < $1.st )
provide error: Anonymous closure argument not contained in a closure
Any idea? :)
My aSoundTracks_Filtered was delared like this:
var aSoundTracks_Filtered = [SoundTrack]()
My struct was like this:
struct SoundTrack {
let sID : Int
let st : String
}
Your code works fine when you tested in a Playground in the following way:
struct SoundTrack {
let sID : Int
let st : String
}
var aSoundTracks_Filtered = [SoundTrack]()
aSoundTracks_Filtered.append(SoundTrack(sID: 1, st: "a"))
aSoundTracks_Filtered.append(SoundTrack(sID: 2, st: "b"))
aSoundTracks_Filtered.sort{ $0.st > $1.st } // [{sID 2, st "b"}, {sID 1, st "a"}]
But sort() sorts an array in-place. What you probably want to use is sorted(), which does not modify the original array and returns a new sorted array:
let aRes = aSoundTracks_Filtered.sorted{ $0.st > $1.st }
The above code is for Swift 1.2, for Swift 2.0 returning a sorted array is called "sort" again, but it is a (protocol extension) method now instead of a global function. I hope this help you.
So, it's actually pretty simple. However I wonder where the selfcomes from when you access the array. I don't know which class it belongs to, in case it would belong to the struct itself (I wouldn't know why but just in case) you'll have to mark the function as mutating as you're changing the value of a struct's attribute. The second thing is actually that you'll have to use curley brackets:
self.aSoundTracks_Filtered.sort({$0.st < $1.st})

Resources