I'm looking to add an array for a string variable inside of a struct I have created in Go.
type Recipes struct { //Struct for recipe information
name string
prepTime int
cookTime int
recipeIngredient string
recipeID int
recipeYield int
}
It is called by
Recipe1.name = "BBQ Pulled Chicken"
Recipe1.prepTime = 25
Recipe1.cookTime = 5
Recipe1.recipeIngredient = "1 8-ounce can reduced-sodium tomato sauce, two"
Recipe1.recipeID = 1
Recipe1.recipeYield = 8
recipeIngredient will have multiple ingredients so it just can't be one string. I would like to have multiple array/slice elements inside recipeIngredient. Anyone have an idea on how i would be able to do this please?
Use a slice of string. For example,
package main
import "fmt"
type Recipe struct {
Name string
PrepTime int
CookTime int
Ingredients []string
ID int
Yield int
}
func main() {
var recipe Recipe
recipe.Name = "BBQ Pulled Chicken"
recipe.PrepTime = 25
recipe.CookTime = 5
recipe.Ingredients = append(recipe.Ingredients,
"1 8-ounce can reduced-sodium tomato sauce",
)
recipe.Ingredients = append(recipe.Ingredients,
"1/2 medium onion, grated ",
)
recipe.ID = 1
recipe.Yield = 8
fmt.Println(recipe)
fmt.Printf("Ingredients: %q\n", recipe.Ingredients)
}
Output:
{BBQ Pulled Chicken 25 5 [1 8-ounce can reduced-sodium tomato sauce 1/2 medium onion, grated ] 1 8}
Ingredients: ["1 8-ounce can reduced-sodium tomato sauce" "1/2 medium onion, grated "]
Related
I'm using Apache Thrift to define a struct.
struct Base {
1:string ID (go.tag = 'bson:"_id" json:"id,omitempty"')
}
After executing the command "thrift --gen go base.thrift"
I want it to look like this.
type Base struct {
ID bson.ObjectId `bson:"_id" json:"id,omitempty"`
}
bson.ObjectId comes from github.com/globalsign/mgo/bson
// NewObjectId returns a new unique ObjectId.
func NewObjectId() ObjectId {
var b [12]byte
// Timestamp, 4 bytes, big endian
binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix()))
// Machine, first 3 bytes of md5(hostname)
b[4] = machineId[0]
b[5] = machineId[1]
b[6] = machineId[2]
// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
b[7] = byte(processId >> 8)
b[8] = byte(processId)
// Increment, 3 bytes, big endian
i := atomic.AddUint32(&objectIdCounter, 1)
b[9] = byte(i >> 16)
b[10] = byte(i >> 8)
b[11] = byte(i)
return ObjectId(b[:])
}
I have an array of subarrays in the following format
Array
(
[0] => Array
(
[unit_id] => 6504
[assignment_name] => Grade assignment
[assignment_description] =>
[assignment_total_score] => 10
[unit_type_name] => Homework
[is_graded] => 1
[standard_id] => 1219
[scoring_type] => score
[attempt_score] => 8
[unit_duedate] => 2016-02-10 09:00:00
[standard] => Array
(
[0] => stdClass Object
(
[unit_id] => 6504
[is_formal] => 1
[assignment_name] => Grade assignment
[assignment_description] =>
[standard_id] => 1220
[standard_name] => 9-10.RL.3
[standard_description] => Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a
)
)
)
[1] => Array
(
[unit_id] => 8584
[assignment_name] => Sine and Cosecant Graphs
[assignment_description] => Define the sine and cosecant graphs using a unit circle
[assignment_total_score] => 15
[unit_type_name] => Paper
[scoring_type] => score
[attempt_score] => 0
[unit_duedate] => 2016-04-29 09:00:00
[standard] => Array
(
[0] => stdClass Object
(
[unit_id] => 8584
[is_formal] => 1
[assignment_name] => Sine and Cosecant Graphs
[assignment_description] => Define the sine and cosecant graphs using a unit circle
[assignment_total_score] => 15
[standard_id] => 82790
[standard_name] => 9-10.RL.7
)
)
[2] => Array
(
[unit_id] => 11611
[assignment_name] => Adding 5 + 3 + 6
[assignment_description] =>
[assignment_total_score] => 10
[unit_type_name] => Homework
[standard_id] => 82772
[scoring_type] => score
[attempt_score] => 0
[unit_duedate] => 2016-08-23 19:00:00
[standard] => Array
(
[0] => stdClass Object
(
[unit_id] => 11611
[is_formal] => 1
[assignment_name] => Adding 5 + 3 + 6
[assignment_description] =>
[assignment_total_score] => 10
[standard_id] => 82772
[standard_name] => 9-10.RL.1
)
)
)
)
And I would like to group it into a new slice based on the unit_type_name field in each subarray.
How can I group the slice by unit_type_name? Is there any native Go functions are available to do this?
if I for loop the above then I will get a duplicate one, how can I avoid that?
I do not think Go has a built-in functionality to help you do that (I may be wrong). My Assumption is that the PHP array will be converted to a JSON object. I managed to get the code below to help you sort your array (In JSON format) a based on the unit_type_name
I created two structs which have JSON values similar to what the array keys would be
//StandardType ...
type StandardType struct {
UnitID int `json:"unit_id"`
IsFormal int `json:"is_formal"`
AssignmentName string `json:"assignment_name"`
AssignmentDescription string `json:"assignment_description"`
StandardID int `json:"standard_id"`
StandardName string `json:"standard_name"`
StandardDescription string `json:"standard_description"`
}
//AutoGenerated ...
type AutoGenerated struct {
UnitID int `json:"unit_id"`
AssignmentName string `json:"assignment_name"`
AssignmentDescription string `json:"assignment_description"`
AssignmentTotalScore int `json:"assignment_total_score"`
UnitTypeName string `json:"unit_type_name"`
IsGraded int `json:"is_graded"`
StandardID int `json:"standard_id"`
ScoringType string `json:"scoring_type"`
AttemptScore int `json:"attempt_score"`
UnitDuedate string `json:"unit_duedate"`
Standard []StandardType `json:"standard"`
}
var jsonData = ``
func main() {
m := []AutoGenerated{}
err := json.Unmarshal([]byte(jsonData), &m)
if err != nil {
panic(err)
}
I created a map to hold the unit_type_name keys
sliceKeys := make(map[string]string)
I created also map to hold the arrays that have similar unit_type_name keys in an AutoGenerated array
groupedSlices := make(map[string][]AutoGenerated)
Then I loop through the decoded JSON string searching for the unit_type_name
for i := range m {
If a unit_type_name already exists in the key slice I add the array item to the group slice
if _, ok := sliceKeys[m[i].UnitTypeName]; ok {
autogenerated := groupedSlices[m[i].UnitTypeName]
autogenerated = append(autogenerated, m[i])
groupedSlices[m[i].UnitTypeName] = autogenerated
} else {
Else I create a new array key and add the item to it
sliceKeys[m[i].UnitTypeName] = m[i].UnitTypeName
autogenerated := []AutoGenerated{}
autogenerated = append(autogenerated, m[i])
groupedSlices[m[i].UnitTypeName] = autogenerated
}
}
fmt.Println(sliceKeys)
fmt.Println(groupedSlices)
}
input:
[{"unit_id": 6504,"assignment_name": "Grade assignment","assignment_description": "","assignment_total_score": 10,"unit_type_name": "Homework","is_graded": 1,"standard_id": 1219,
"scoring_type": "score","attempt_score": 8,"unit_duedate": "2016-02-10 09:00:00",
"standard": [{"unit_id": 6504,"is_formal": 1,"assignment_name": "Grade assignment","assignment_description": "",
"standard_id": 1220,"standard_name": "9-10.RL.3","standard_description": "Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a "
}]},{"unit_id": 6504,"assignment_name": "Grade assignment","assignment_description": "","assignment_total_score": 10,
"unit_type_name": "Paper","is_graded": 1,"standard_id": 1219,"scoring_type": "score","attempt_score": 8,"unit_duedate": "2016-02-10 09:00:00","standard": [{"unit_id": 6504,"is_formal": 1,"assignment_name": "Grade assignment","assignment_description": "","standard_id": 1220,"standard_name": "9-10.RL.3","standard_description": "Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a "}]},{
"unit_id": 6504,"assignment_name": "Grade assignment","assignment_description": "",
"assignment_total_score": 10,"unit_type_name": "Aything else","is_graded": 1,"standard_id": 1219,
"scoring_type": "score","attempt_score": 8,"unit_duedate": "2016-02-10 09:00:00","standard": [{
"unit_id": 6504,"is_formal": 1,"assignment_name": "Grade assignment","assignment_description": "","standard_id": 1220,
"standard_name": "9-10.RL.3","standard_description": "Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a "}]}]
output:
map[Homework:Homework Paper:Paper Aything else:Aything else]
map[
Homework:[
{6504 Grade assignment 10 Homework 1 1219 score 8 2016-02-10 09:00:00 [{6504 1 Grade assignment 1220 9-10.RL.3 Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a }]}
]
Paper:[
{6504 Grade assignment 10 Paper 1 1219 score 8 2016-02-10 09:00:00 [{6504 1 Grade assignment 1220 9-10.RL.3 Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a }]}
]
Aything else:[
{6504 Grade assignment 10 Aything else 1 1219 score 8 2016-02-10 09:00:00 [{6504 1 Grade assignment 1220 9-10.RL.3 Analyze how complex characters (e.g., those with multiple or conflicting motivations) develop over the course of a }]}]
]
Here is a general GroupBy function I wrote:
// Created by BaiJiFeiLong#gmail.com at 2021/8/27 10:51
package main
import (
"fmt"
"reflect"
"strconv"
)
func GroupBy(arr interface{}, groupFunc interface{}) interface{} {
groupMap := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(groupFunc).Out(0), reflect.TypeOf(arr)))
for i := 0; i < reflect.ValueOf(arr).Len(); i++ {
groupPivot := reflect.ValueOf(groupFunc).Call([]reflect.Value{reflect.ValueOf(arr).Index(i)})[0]
if !groupMap.MapIndex(groupPivot).IsValid() {
groupMap.SetMapIndex(groupPivot, reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(arr).Elem()), 0, 0))
}
groupMap.SetMapIndex(groupPivot, reflect.Append(groupMap.MapIndex(groupPivot), reflect.ValueOf(arr).Index(i)))
}
return groupMap.Interface()
}
func main() {
fmt.Println(GroupBy([]int{1, 22, 3, 44, 555}, func(value int) string {
return strconv.Itoa(len(strconv.Itoa(value)))
}))
}
The output:
map[1:[1 3] 2:[22 44] 3:[555]]
For your question, it shoube be some code like:
group := GroupBy(items, func(item Item) string {
return item.UnitTypeName
}).(map[string][]Item)
For example if I have a string {a, b, c}. I need to print out on the console all the permutations without repeating letters from 1 letter to 3 letters like this:
a b c ab ac abc acb ba bc bac bca ca cb cab cba
How can I write this using recursion?
If you need all the permutations of the chars into a String you can use a recursive function.
Here's the code in Swift.
func visit(unused:[Character], used: [Character] = [Character]()) -> [String] {
var result = [String(used)]
for (index, char) in unused.enumerate() {
var unused = unused
unused.removeAtIndex(index)
var used = used
used.append(char)
result = result + visit(unused, used: used)
}
return result
}
As you can see the function receives 2 params:
unused: represents the list of chars not yet used
used: the chars used to build possible element of the ouput. This parameter is optional so if it's not passed to the function, an empty array is used (this is useful for the first invocation).
Test
let word = "abc"
let chars = [Character](word.characters)
print(visit(chars))
["", "a", "ab", "abc", "ac", "acb", "b", "ba", "bac", "bc", "bca", "c", "ca", "cab", "cb", "cba"]
Omitting the empty String
This results also contains the empty String but you can easily omit this value just update the function as shown below.
func visit(unused:[Character], used: [Character] = [Character]()) -> [String] {
var result = [String]()
if !used.isEmpty {
result.append(String(used))
}
for (index, char) in unused.enumerate() {
var unused = unused
unused.removeAtIndex(index)
var used = used
used.append(char)
result = result + visit(unused, used: used)
}
return result
}
I have
const (
BlahFoo = 1 << iota
MooFoo
)
then
type Cluster struct {
a int
b int
}
I want Cluster.a to only be BlahFoo or MooFoo
How do I enforce that?
type FooEnum int
const (
BlahFoo FooEnum = 1 << iota
MooFoo
)
type Cluster struct {
a FooEnum
b int
}
I can sort a table with two pieces of information (the name and a second piece, such as age) with the following code:
t = {
Steve = 4,
Derek = 1,
Mike = 5,
Steph = 10,
Mary = 7,
Danny = 2
}
function pairsByKeys (t,f)
local a = {}
for x in pairs (t) do
a[#a + 1] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end
for a,t in pairsByKeys (t) do
print (a,t)
end
Result:
Danny 2
Derek 1
Mary 7
Mike 5
Steph 10
Steve 4
I have a scenario where at a convention each person's name tag contains a barcode. This barcode, when scanned, enters four pieces of information about each person into a table database. This database is made up of the following pieces:
t = {
{name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"}
{name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"}
{name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"}
}
But how would I change my code to sort all four entries (name, addr, age, phone) by age and keep all variables in line with one another?
I've been trying to experiment and am getting the hang of sorting a table by pairs and have a better idea how to perform table.sort. But now I want to take this another step.
Can I please receive some help from one of the programming gurus here?! It is greatly appreciated guys! Thanks!
You could use the age as the key of your table:
t = {
[30] = {name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
[28] = {name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
[34] = {name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}
function pairsByKeys (t,f)
local a = {}
for x in pairs (t) do
a[#a + 1] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end
for a,t in pairsByKeys (t) do
print (t.name, t.addr, t.age, t.phone)
end
EDIT
Otherwise, if you don't want to change the structure of t, you could change your iterator generating function to keep track of the indexing:
t = {
{name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
{name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
{name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}
function pairsByAgeField(t,f)
local a = {}
local index = {}
for _, x in pairs(t) do
local age = x.age
a[#a + 1] = age
index[age] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], index[a[i]]
end
end
for a,t in pairsByAgeField(t) do
print (t.name, t.addr, t.age, t.phone)
end
Of course this makes pairsByAgeField less generally applicable than your original pairsByKeys (it assumes that the table being iterated has a given structure), but this is not a problem if you often have to deal with tables such as t in your application.