I have a data with array of array.
data := [][]int{{1,2,3}, {4,5,6}}
and struct
type A struct {
I, J, K int
}
Now I want to create instance run time for struct A with each array from data, How do I achieve that? If reflect is a way, then tell how?
This is just an example that I want to show you. But let's say if struct A contains 26 fields from A to Z with type of int and I have 100 slices of data from which I can create/init my struct A, then how it could be possible without using dot notation on struct and just looping over field index and assign that field from slice data?
package main
import (
"fmt"
)
type A struct {
I, J, K int
}
func main() {
data := [][]int{
{1, 2, 3},
{4, 3, 2},
}
var a A
// create instance of type A with params
// initialization for each array in data
fmt.Println(a)
}
Please help me at this link: https://play.golang.org/p/rYuoajn5Ln
I'm not sure if that is what you are looking for, but you can create those objects in a simple loop:
func main() {
data := [][]int{
{1, 2, 3},
{4, 3, 2},
}
for _, intArr := range data {
a := NewA(intArr)
// a:= A{I: ints[0], J: ints[1], K: ints[2]}
fmt.Println(a)
}
}
Full solution available at https://play.golang.org/p/j7fxbmu3jp
Here it is, for a more compact version...
Just range over your "data" array of arrays and create a new "A" from each index.
No need to do that in a separate function.
for _, arr := range data {
a := A{I: arr[0], J: arr[1], K: arr[2]}
fmt.Println(a)
}
Full solution here: https://play.golang.org/p/jyN7f9c-o-
Related
How can I convert []int into [3]int?
non of those work:
vec := []int{1, 2, 3}
t1 := [3]int(vec)
t2 := [3]int(vec[:])
//cannot convert vec (variable of type []int) to [3]int
t3 := [3]int{}
copy(t3, vec)
//invalid argument: copy expects slice arguments; found t3 (variable of type [3]int) and vec
//(value of type []int)
Here's a Go playground example that might make it more clear what's going on with copy(t3[:],vec).
Go Playground example code :
package main
import (
"fmt"
)
func main() {
slice := []int{1, 2, 3, 4}
var array [3]int
arrayAsSlice := array[:] // arrayAsSlice storage IS array; they are aliased.
copy(arrayAsSlice, slice[:3]) // copy into arrayAsSlice modifies array, too.
arrayAsSlice[0] = -1 // slice and array are STILL aliased
arrayAsSlice = append(arrayAsSlice, 99) // slice cannot grow in the memory it has, therefore, it is reallocated.
arrayAsSlice[0] = 0 // Now slice and array are NOT aliased, so this does not modify the array
fmt.Printf("Hello, playground, %+v", array)
}
This question already has answers here:
How to find out element position in slice?
(10 answers)
Closed 2 years ago.
I am trying to find out the equivalent of indexof to get the position of specific element in array golang the purpose for integers in array.
package main
import (
"fmt"
)
func main() {
fmt.Println("what")
arr := []int{1, 2, 3, 4, 2, 2, 3, 5, 4, 4, 1, 6}
i := IndexOf(2, arr)
}
Write a function. Here's an example assuming that IndexOf returns the first index of the number or -1 if none is found.
// IndexOf returns the first index of needle in haystack
// or -1 if needle is not in haystack.
func IndexOf(haystack []int, needle int) int {
for i, v := range haystack {
if v == needle {
return i
}
}
return -1
}
Run this code on the Go Programming Language Playground.
There is no common library function to do this for you in go.
However if you are using a byte slice, you can use IndexByte(b []byte, c byte) int.
Or you can write a quick function which does this for you:
func indexOf(arr []int, val int) int {
for pos, v := range arr {
if v == val {
return pos
}
}
return -1
}
package main
import "fmt"
func IndexOf(arr []int, candidate int) int {
for index, c := range arr {
if c == candidate {
return index
}
}
return -1
}
func main() {
fmt.Println("what")
arr := []int{1, 2, 3, 4, 2, 2, 3, 5, 4, 4, 1, 6}
i := IndexOf(arr, 2)
fmt.Println(i)
}
Add a method IndexOf to search, this is a linear search method.
Ref: https://play.golang.org/p/Hp6Dg--XoIV
There is no equivalent for IndexOf in Go. You need to implement one your self. But if you have have sorted array of Ints, you can use sort.SearchInts as shown below.
package main
import (
"fmt"
"sort"
)
func main() {
fmt.Println(sort.SearchInts([]int{2,3,4,5,9,10,11}, 5))
}
Also from the godoc:
SearchInts searches for x in a sorted slice of ints and returns the index as specified by Search. The return value is the index to insert x if x is not present (it could be len(a)). The slice must be sorted in ascending order.
Probably just because I'm new to Go, but using the range syntax over arrays of structs doesn't behave as I'd expect. I'm assuming the array item gets copied to the range index, but the copy isn't a deep copy ... so the following is a little weird. Is this behaviour documented somewhere
package main
import "fmt"
type Inner struct {
x, y int
}
type Attr struct {
a int
inside []Inner
}
var item = []Attr{
{a: 1, inside: []Inner{{2, 3}, {3, 4}}},
{a: 2, inside: []Inner{{3, 4}, {1, 2}}},
}
func main() {
fmt.Println(item)
for _,i := range item {
// A: The following has no impact on item[].a
i.a = 111
// B: But this does ... why?
i.inside[0].x = 111
}
fmt.Println(item)
for j,_ := range item {
item[j].a = 333
item[j].inside[0].x = 333
}
fmt.Println(item)
}
In the loop for _, i := range item, each i is a copy of the corresponding slice element. Suppose, you write:
i := item[0]
i.a = 111
this does not change the original element of the slice, but only its copy. However in:
i.inside[0].x = 111
inside is a slice, i.e. only a thin wrapper referring to the underlying array, which is not copied on assignment. So with i.inside you deal with the same slice as items[0].inside.
More about slices internals.
This question already has answers here:
What is the shortest way to simply sort an array of structs by (arbitrary) field names?
(6 answers)
Closed 26 days ago.
Let's say I have struct SortableStruct with 3 fields A B C I want to implement function that consumes sl []SortableStruct and orderFied string where orderField is one of struct's field. This function should retrun slice sorted by orderField. Is there a way of doing this without huge switch case. It's not ovious for me how to implement sort.Interface when I want compare structs by different fields.
Well, easiest way is to switch field type and assign a SORT function. Here is your code:
package main
import (
"fmt"
"sort"
)
type SortableStruct struct {
A int
B int
C int
}
func sortStruct(arr []SortableStruct, field string) {
var less func(i, j int) bool
switch field {
case "B":
less = func(i, j int) bool {
return arr[i].B < arr[j].B
}
case "C":
less = func(i, j int) bool {
return arr[i].C < arr[j].C
}
default:
less = func(i, j int) bool {
return arr[i].A < arr[j].A
}
}
sort.Slice(arr, less)
}
func main() {
arr := []SortableStruct{
{
A: 1,
B: 5,
C: 3,
},
{
A: 2,
B: 3,
C: 20,
},
{
A: -1,
B: -1,
C: 10,
},
}
sortStruct(arr, "C")
fmt.Println(arr)
}
Another idea would be to have 3 defined types, each of them implementing interface sort.Interface
type SortableStructByA []SortableStruct
type SortableStructByB []SortableStruct
type SortableStructByC []SortableStruct
And then, you will have to cast your slice to the wanted type(depending on sort you want) and to do something like this:
sortableSlice := SortableStructByA(arr)
sort.Sort(sortableSlice)
I'm currently writing a program and I want to randomly generate a matrix.
Currently I'm pre-setting the values in it as follows:
m1 := [3][3]int{
[3]int{1, 1, 1},
[3]int{4, 1, 7},
[3]int{1, 65, 1},
}
However I want the values inputted to be randomly generated in a range from 1-100.
import "math/rand"
I am importing the above library and trying to utilise it.
I have attempted to get this working however can't seem to make any headway.
m1 := [3][3]int{
[3]int{rand.Intn, 1, 1},
[3]int{4, 1, 7},
[3]int{1, 65, 1},
}
I have attempted to complete it with the above solution to make the first number random however I get the following error.
cannot use rand.Intn (type func(int) int) as type int in array or slice literal
Any help greatly appreciated.
The direct answer is the fact that rand.Intn() generates a random integer between 0 and n, where n is a parameter to this method. The error that you are getting is the compiler complaining that you are trying to initialize an int value with a function that requires two ints and returns one - you are trying to assign a function to an int. So the correct call would be something like rand.Intn(100), which will give you a random number between 0 - 100.
However, why do it this way? Why not dynamically initialize your array with random numbers as:
m1 := [3][3]int{}
for i:=0; i<3; i++ {
for j:=0; j<3; j++ {
m1[i][j] = rand.Int()
}
}
Answer to your question is answered above, this is an extension,
While rand.Int(10) always gives you 1, as it isn't seeded,
you can add this function to get random values each time you run your program,
package main
import (
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
//we are seeding the rand variable with present time
//so that we would get different output each time
}
func main() {
randMatrix := make([][]int, 3)
// we have created a slice with length 3
//which can hold type []int, these can be of different length
for i := 0; i < 3; i++ {
randMatrix[i] = make([]int, 3)
// we are creating a slice which can hold type int
}
generate(randMatrix)
fmt.Println(randMatrix)
}
func generate(randMatrix [][]int) {
for i, innerArray := range randMatrix {
for j := range innerArray {
randMatrix[i][j] = rand.Intn(100)
//looping over each element of array and assigning it a random variable
}
}
}
This code generates random Matrix, below 100, while you can also use flags for any kind of future use and generalize the values,
import "flag"
var outerDim, innerDim, limit *int
func main() {
outerDim = flag.Int("outerDim", 3, "Outer dimension of the matrix")
innerDim = flag.Int("innerDim", 3, "inner dimenstion of the matrix")
limit = flag.Int("limit", 100, "matrix values are limited specified value")
flag.Parse()
randMatrix := make([][]int, *outerDim)
for i := 0; i < *outerDim; i++ {
randMatrix[i] = make([]int, *innerDim)
}
generate(randMatrix)
printMatrix(randMatrix)
}
func generate(randMatrix [][]int) {
for i, innerArray := range randMatrix {
for j := range innerArray {
randMatrix[i][j] = rand.Intn(*limit)
}
}
}
func printMatrix(randMatrix [][]int) {
//looping over 2D slice and extracting 1D slice to val
for _, val := range randMatrix {
fmt.Println(val)// printing each slice
}
}
We could modify the printMatrix function above, by looping over each integer and then formatting it well by using fmt.Printf(), but that would complicate things when we don't known the length of the limit...