问题
I have data that is created rows by rows, 6 columns, I don't know the final number of rows in advance.
Currently i'm creating a 2D slice of 200x6 with all zeros and then i replace these zeros gradually with my data, row by row. The data comes from another dataframe df
It works but i don't like to end up with the last rows of my slice full of zeros. I see 2 solutions: - I delete all the last rows with only zeros when I'm done - I create an empty slice and append my data progressively to it
I tried various things but could not figure out how to code any of these 2 solutions.
Currently my code looks like this:
var orders [200][6]float64 // create my 2d slice with zeros
order_line := 0
for i := start_line; i <= end_line; i++ {
if sell_signal == "1" {
//record line number and sold price in orders slice
orders[order_line][1] = float64(i+1)
orders[order_line][2],err = strconv.ParseFloat(df[i][11], 64)
order_line = order_line + 1
}
}
I looked at the Append command, but I tried all sorts of combinations to make it work on a 2d slice, could not find one that works.
edit: from the comments below I understand that i'm actually creating an array, not a slice, and there is no way to append data to an array.
回答1:
Given that the outer container has an unknown number of elements and the inner container has exactly six elements, use a slice of arrays.
var orders [][6]float64
for i := start_line; i <= end_line; i++ {
if sell_signal == "1" {
n, err = strconv.ParseFloat(df[i][11], 64)
if err != nil {
// handle error
}
orders = append(orders, [6]float64{1: float64(i + 1), 2: n})
}
}
This code uses a composite literal [6]float64 value instead of assigning element by element as in the question.
You can come back and access elements of the [6]float64 at a later time. For example:
orders[i][3] = orders[i][1] + orders[i][2]
回答2:
In Golang slices are preferred in place of arrays.
Creating so many rows in prior is not required, just create a slice every time you are looping over your data to add a new row in the parent slice. That will help you to have only required number of rows and you need to worry about the length Since you are appending a slice at an index of parent slice.
package main
import (
"fmt"
"math/rand"
)
func main() {
orders := make([][]float64, 0) // create my 2d slice with zeros
for i := 0; i <= 6; i++ {
value := rand.Float64()
temp := make([]float64, 0)
temp = append(temp, value)
orders = append(orders, [][]float64{temp}...)
}
fmt.Println(orders)
}
Please check working code on Playground
If you notice I am creating a new temp
slice in loop which contains the float64
value and then appending value to the temp slice which I have passed to the parent slice.
So everytime I append the temp slice to the parent slice a new row will be created.
Note:
Arrays have their place, but they're a bit inflexible, so you don't see them too often in Go code. Slices, though, are everywhere. They build on arrays to provide great power and convenience.
Edited:
To work on first 3 columns and then manipulate the values for next 3 columns which will be added to the temp slice and appended to the main slice. Use below code logic:
package main
import (
"fmt"
"math/rand"
"strconv"
)
func main() {
orders := make([][]float64, 0) // create my 2d slice with zeros
for i := 0; i <= 6; i++ {
value := rand.Float64()
// logic to create first 3 columns
temp := make([]float64, 0)
temp = append(temp, value)
temp2 := make([]float64, 3)
// logic to create next 3 columns on basis of previous 3 columns
for j, value := range temp {
addcounter, _ := strconv.ParseFloat("1", 64)
temp2[j] = value + addcounter
}
temp = append(temp, temp2...)
orders = append(orders, [][]float64{temp}...)
}
fmt.Println(orders)
}
Working Example
回答3:
For better readability, and easier slice handling, just create a struct type and fill a slice with them. This allows you to properly name each field instead of magic index numbers and makes it easier to fill in the rows as well as utilize later. Unless there is some specific reason to use arrays/slices for the columns, this is more idiomatic Go. The following example would fill a slice with however many results you have, and no more.
Full example here: https://play.golang.org/p/mLtabqO8MNj
type Row struct {
Thing float64
Data float64
More float64
Stuff float64
Another float64
Number float64
}
var rows []*Row
numResults := 15
for i := 0; i <= numResults; i++ {
row := &Row{}
row.Thing = 2.5
// ... fill values
rows = append(rows, row)
}
来源:https://stackoverflow.com/questions/52706495/how-to-append-to-a-2d-slice