Arrays GO:如何分配可变大小的2×2数组中的所有元素?

Arrays GO:如何分配可变大小的2×2数组中的所有元素?,arrays,go,slice,Arrays,Go,Slice,我在使用GO用文本文件中的矩阵填充2D数组时遇到问题 我的主要问题是创建2D数组,因为我必须计算数组的维数,而GO似乎不接受数组维数中的VAR: nb_lines = number of line of the array nb_col = number of columns of the array // read matrix from file whole_file,_ := ioutil.ReadFile("test2.txt") // get each line of the fil

我在使用GO用文本文件中的矩阵填充2D数组时遇到问题

我的主要问题是创建2D数组,因为我必须计算数组的维数,而GO似乎不接受数组维数中的VAR:

nb_lines = number of line of the array
nb_col = number of columns of the array

// read matrix from file
whole_file,_ := ioutil.ReadFile("test2.txt")
// get each line of the file in tab_whole_file
tab_whole_file := strings.Split(string(whole_file), "\n")
// first line of the table
tab_first_line := strings.Split(tab_whole_file[0], "\t")
nb_col := len(tab_first_line)
nb_lines := len(tab_whole_file) - 1

// at this point I tried to build a array to contain the matrix values from the texte file

var columns [nb_lines][nb_col]float64 // does not work
columns := make([][]float64, nb_lines, nb_col) // does not work
columns := make([nb_lines][nb_col]float64) // does not work
columns := [nb_lines][nb_col]float64{} // does not work
columns := [][]float64{} // panic: runtime error: index out of range

for i := 0; i < nb_lines ; i++ { // for each line of the table from text file
    line := strings.Split(tab_whole_file[0], "\t") // split one line to get each table values
    for j := 1; j < len(line) ; j++ {
        columns[i][j], _  = strconv.ParseFloat(line[j], 64) // assign each value to the table columns[i][j]
    }
}
nb\u行数=数组的行数
nb_col=数组的列数
//从文件中读取矩阵
整个文件,\:=ioutil.ReadFile(“test2.txt”)
//在tab_文件中获取文件的每一行
tab_整_文件:=strings.Split(string(整_文件),“\n”)
//表的第一行
tab\u第一行:=strings.Split(tab\u整个文件[0],“\t”)
nb\U col:=len(制表符第一行)
nb_行:=len(制表符整个文件)-1
//此时,我尝试构建一个数组来包含texte文件中的矩阵值
var columns[nb_line][nb_col]float64//不起作用
列:=make([]float64,nb\u行,nb\u列)//不工作
列:=make([nb_line][nb_col]float64)//不起作用
列:=[nb_行][nb_列]float64{}//不起作用
列:=[]float64{}//panic:运行时错误:索引超出范围
对于i:=0;i
Go中
float64
的矩阵被声明为
[]float64

var matrix [][]float64
您可以使用
:=
运算符初始化矩阵并自动声明类型

matrix := [][]float64{}
请注意,上面这一行不是简单的声明,而是用于创建新空切片的语法

// creates an empty slice of ints
x := []int{} 
// creates a slice of ints
x := []int{1, 2, 3, 4} 
使用
[]float64{}
将定义和分配结合在一起。请注意,以下两行是不同的

// creates a slice of 4 ints
x := []int{1, 2, 3, 4} 
// creates an array of 4 ints
x := [4]int{1, 2, 3, 4} 
切片可以调整大小,数组具有固定大小

回到您的问题,这演示了如何创建
float64
的矩阵,并将新行附加到矩阵中

package main

import "fmt"

func main() {
    matrix := [][]float64{}
    matrix = append(matrix, []float64{1.0, 2.0, 3.0})
    matrix = append(matrix, []float64{1.1, 2.1, 3.1})
    fmt.Println(matrix)
}

你可以从这个例子开始,更新你的脚本。

我对我的程序做了一些修改,这是一个“几乎”可行的例子。。。不太优雅;)矩阵中仍然存在一个问题:矩阵的第一列对应于文件的第一行,因此我无法访问列:(

func main(){
矩阵:=[]float64{}//对应于文本文件的矩阵
//打开文件。
整个文件,\:=ioutil.ReadFile(“test2.tsv”)
//请确定桌子的大小
tab_整_文件:=strings.Split(string(整_文件),“\n”)
tab\u第一行:=strings.Split(tab\u整个文件[0],“\t”)
nb\U col:=len(制表符第一行)
nb_行:=len(制表符整个文件)-1
//我不知道为什么这个数字比我预期的要长,所以我不得不减去1
对于i:=0;i
例如

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "strconv"
)

func loadMatrix(filename string) ([][]float64, error) {
    var m [][]float64
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }

    rows := bytes.Split(data, []byte{'\n'})
    for r := len(rows) - 1; r >= 0; r-- {
        if len(rows[r]) != 0 {
            break
        }
        rows = rows[:len(rows)-1]
    }
    m = make([][]float64, len(rows))

    nCols := 0
    for r, row := range rows {
        cols := bytes.Split(row, []byte{'\t'})
        if r == 0 {
            nCols = len(cols)
        }
        m[r] = make([]float64, nCols)
        for c, col := range cols {
            if c < nCols && len(col) > 0 {
                e, err := strconv.ParseFloat(string(col), 64)
                if err != nil {
                    return nil, err
                }
                m[r][c] = e
            }
        }
    }
    return m, nil
}

func main() {
    filename := "matrix.tsv"
    m, err := loadMatrix(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Matrix:")
    fmt.Println(m)

    fmt.Println("\nBy [row,column]:")
    for r := range m {
        for c := range m[0] {
            fmt.Printf("[%d,%d] %5v  ", r, c, m[r][c])
        }
        fmt.Println()
    }

    fmt.Println("\nBy [column,row]:")
    for c := range m[0] {
        for r := range m {
            fmt.Printf("[%d,%d] %5v  ", c, r, m[r][c])
        }
        fmt.Println()
    }
}

Go是一种静态类型语言,数组的长度是其类型的一部分。这意味着数组的长度必须是编译时常量。在Go中,如果需要分配可变长度的“数组”动态地,您使用切片来代替。非常感谢您的回答Simone。您的解决方案很适合处理行。不幸的是,我必须处理列,因此使用索引数组[I][j]填充数组如果我有一个解决方案来创建具有行数和列数的数组会更好。非常感谢您提供了这段非常好的代码!如果我需要访问矩阵的列,请参见[3.14 42]对于col1,唯一的方法是从m@Fred构建另一个转置矩阵:第一个矩阵索引表示行,第二个表示列:
m[r,c]
。使用索引选择特定的行或列。请参阅我的修订答案。再次感谢您,彼得索!与其他一些编程语言(Python、Perl、Julia、R…)相比,仅读取表格所需的工作量是巨大的!我测试了你的代码,现在我可以访问矩阵的任何元素。但是当我尝试一次访问一列时,我没有得到我想象的结果。例如,m[1][:]和m[:][1]给出完全相同的结果=表的第二行,而不是第二行和第二列。而m[4][2]给出我期望的结果!真奇怪!:)
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "strconv"
)

func loadMatrix(filename string) ([][]float64, error) {
    var m [][]float64
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }

    rows := bytes.Split(data, []byte{'\n'})
    for r := len(rows) - 1; r >= 0; r-- {
        if len(rows[r]) != 0 {
            break
        }
        rows = rows[:len(rows)-1]
    }
    m = make([][]float64, len(rows))

    nCols := 0
    for r, row := range rows {
        cols := bytes.Split(row, []byte{'\t'})
        if r == 0 {
            nCols = len(cols)
        }
        m[r] = make([]float64, nCols)
        for c, col := range cols {
            if c < nCols && len(col) > 0 {
                e, err := strconv.ParseFloat(string(col), 64)
                if err != nil {
                    return nil, err
                }
                m[r][c] = e
            }
        }
    }
    return m, nil
}

func main() {
    filename := "matrix.tsv"
    m, err := loadMatrix(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Matrix:")
    fmt.Println(m)

    fmt.Println("\nBy [row,column]:")
    for r := range m {
        for c := range m[0] {
            fmt.Printf("[%d,%d] %5v  ", r, c, m[r][c])
        }
        fmt.Println()
    }

    fmt.Println("\nBy [column,row]:")
    for c := range m[0] {
        for r := range m {
            fmt.Printf("[%d,%d] %5v  ", c, r, m[r][c])
        }
        fmt.Println()
    }
}
$ cat matrix.tsv
3.14    1.59    2.7 1.8
42

$ go run matrix.go
Matrix:
[[3.14 1.59 2.7 1.8] [42 0 0 0]]

By [row,column]:
[0,0]  3.14  [0,1]  1.59  [0,2]   2.7  [0,3]   1.8  
[1,0]    42  [1,1]     0  [1,2]     0  [1,3]     0  

By [column,row]:
[0,0]  3.14  [0,1]    42  
[1,0]  1.59  [1,1]     0  
[2,0]   2.7  [2,1]     0  
[3,0]   1.8  [3,1]     0  
$