How to append to a 2d slice

流过昼夜 提交于 2021-01-29 16:14:01

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!