How to create a three-dimensional array in Golang

huangapple go评论122阅读模式
英文:

How to create a three-dimensional array in Golang

问题

我正在尝试创建一个包含块的三维数组(类似魔方)。

我尝试了很多方法,但是无法使其正常工作。

  1. func generateTiles(x int, y int, z int) [][][]*tile{
  2. var tiles [][][]*tile
  3. // 在这里进行一些操作
  4. // 生成一个 x * y * z 的数组
  5. // 并填充为 *tile
  6. return tiles
  7. }

有什么建议吗?

英文:

I'm trying to create a three-dimensional array which contains blocks (like a rubiks-cube).

I tried many things but I can't get it to work.

  1. func generateTiles(x int, y int, z int) [][][]*tile{
  2. var tiles [][][]*tile
  3. // Something here
  4. // resulting in a x by y by z array
  5. // filled with *tile
  6. return tiles
  7. }

Any suggestions?

答案1

得分: 17

你必须为每个层单独初始化。示例代码如下:

  1. tiles := make([][][]*tile, x)
  2. for i := range tiles {
  3. tiles[i] = make([][]*tile, y)
  4. for j := range tiles[i] {
  5. tiles[i][j] = make([]*tile, z)
  6. }
  7. }

你可以在这里查看示例代码:链接

英文:

You have to initialize each layer on its own. Example (on play):

  1. tiles = make([][][]*tile, x)
  2. for i := range tiles {
  3. tiles[i] = make([][]*tile, y)
  4. for j := range tiles[i] {
  5. tiles[i][j] = make([]*tile, z)
  6. }
  7. }

答案2

得分: 8

我个人会出于性能原因使用1D切片,我将其作为一种替代方案添加进来:

  1. type Tile struct {
  2. x, y, z int
  3. }
  4. type Tiles struct {
  5. t []*Tile
  6. w, h, d int
  7. }
  8. func New(w, h, d int) *Tiles {
  9. return &Tiles{
  10. t: make([]*Tile, w*h*d),
  11. w: w,
  12. h: h,
  13. d: d,
  14. }
  15. }
  16. // indexing based on http://stackoverflow.com/a/20266350/145587
  17. func (t *Tiles) At(x, y, z int) *Tile {
  18. idx := t.h*t.w*z + t.w*y
  19. return t.t[idx+x]
  20. }
  21. func (t *Tiles) Set(x, y, z int, val *Tile) {
  22. idx := t.h*t.w*z + t.w*y
  23. t.t[idx+x] = val
  24. }
  25. func fillTiles(w int, h int, d int) *Tiles {
  26. tiles := New(w, h, d)
  27. for x := 0; x < w; x++ {
  28. for y := 0; y < h; y++ {
  29. for z := 0; z < d; z++ {
  30. tiles.Set(x, y, z, &Tile{x, y, z})
  31. }
  32. }
  33. }
  34. return tiles
  35. }

playground

英文:

I'd personally use a 1D slice for performance reasons, I'm adding this as an alternative:

  1. type Tile struct {
  2. x, y, z int
  3. }
  4. type Tiles struct {
  5. t []*Tile
  6. w, h, d int
  7. }
  8. func New(w, h, d int) *Tiles {
  9. return &amp;Tiles{
  10. t: make([]*Tile, w*h*d),
  11. w: w,
  12. h: h,
  13. d: d,
  14. }
  15. }
  16. // indexing based on http://stackoverflow.com/a/20266350/145587
  17. func (t *Tiles) At(x, y, z int) *Tile {
  18. idx := t.h*t.w*z + t.w*y
  19. return t.t[idx+x]
  20. }
  21. func (t *Tiles) Set(x, y, z int, val *Tile) {
  22. idx := t.h*t.w*z + t.w*y
  23. t.t[idx+x] = val
  24. }
  25. func fillTiles(w int, h int, d int) *Tiles {
  26. tiles := New(w, h, d)
  27. for x := 0; x &lt; w; x++ {
  28. for y := 0; y &lt; h; y++ {
  29. for z := 0; z &lt; d; z++ {
  30. tiles.Set(x, y, z, &amp;Tile{x, y, z})
  31. }
  32. }
  33. }
  34. return tiles
  35. }

<kbd>playground</kbd>

答案3

得分: 0

这是一个在GoByExample上创建二维数组的示例:https://gobyexample.com/arrays。你可以将其扩展为三维数组。

以下是我编写的代码:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Tile struct {
  6. value int
  7. }
  8. func create3D(x, y, z int) [][][]*Tile {
  9. result := make([][][]*Tile, x)
  10. for i := 0; i < x; i++ {
  11. result[i] = make([][]*Tile, y)
  12. for j := 0; j < y; j++ {
  13. result[i][j] = make([]*Tile, z)
  14. for k := 0; k < z; k++ {
  15. result[i][j][k] = new(Tile)
  16. result[i][j][k].value = i + j + k
  17. }
  18. }
  19. }
  20. return result
  21. }
  22. func main() {
  23. X := 3
  24. Y := 4
  25. Z := 5
  26. mat := create3D(X, Y, Z)
  27. for i := 0; i < X; i++ {
  28. for j := 0; j < Y; j++ {
  29. for k := 0; k < Z; k++ {
  30. fmt.Printf("%d ", mat[i][j][k].value)
  31. }
  32. fmt.Println()
  33. }
  34. fmt.Println()
  35. }
  36. }

希望对你有帮助!

英文:

There is an example for creating a two dimensional array on GoByExample: https://gobyexample.com/arrays. You should be able to expand that into a three dimensional case.

Here is what I came up with.

CODE

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. type Tile struct {
  6. value int
  7. }
  8. func create3D( x, y, z int) [][][]*Tile {
  9. result := make([][][]*Tile,x)
  10. for i := 0 ; i &lt; x ; i++ {
  11. result[i] = make([][]*Tile,y);
  12. for j := 0; j &lt; y; j++ {
  13. result[i][j] = make([]*Tile,z);
  14. for k := 0 ; k &lt; z; k++ {
  15. result[i][j][k] = new(Tile)
  16. result[i][j][k].value = i + j + k;
  17. }
  18. }
  19. }
  20. return result
  21. }
  22. func main() {
  23. X := 3
  24. Y := 4
  25. Z := 5
  26. mat := create3D( X , Y , Z);
  27. for i := 0; i &lt; X; i++ {
  28. for j := 0 ; j &lt; Y; j++ {
  29. for k := 0 ; k &lt; Z; k++ {
  30. fmt.Printf(&quot;%d &quot;,mat[i][j][k].value)
  31. }
  32. fmt.Println();
  33. }
  34. fmt.Println();
  35. }
  36. }

答案4

得分: -1

这是它的工作原理,但对我来说,这种方法非常低效。使用这么多次的追加操作,感觉很臃肿,应该有更简单的方法。

  1. func generateTiles(x int, y int, z int) [][][]*tile {
  2. var tiles [][][]*tile
  3. for i := 0; i < z; i++ {
  4. var layer [][]*tile
  5. for j := 0; j < y; j++ {
  6. var row []*tile
  7. for k := 0; k < x; k++ {
  8. var t *tile
  9. t = &tile{}
  10. row = append(row, t)
  11. count++
  12. }
  13. layer = append(layer, row)
  14. }
  15. tiles = append(tiles, layer)
  16. }
  17. return tiles
  18. }
英文:

It works like this, but to me this feels very inefficient. Using the append-operation this many times. And it feels bloated, this should be possible in a simpler way.

  1. func generateTiles(x int, y int, z int) [][][]*tile {
  2. var tiles [][][]*tile
  3. for i := 0; i &lt; z; i++ {
  4. var layer [][]*tile
  5. for j := 0; j &lt; y; j++ {
  6. var row []*tile
  7. for k := 0; k &lt; x; k++ {
  8. var t *tile
  9. t = &amp;tile{}
  10. row = append(row, t)
  11. count++
  12. }
  13. layer = append(layer, row)
  14. }
  15. tiles = append(tiles, layer)
  16. }
  17. return tiles
  18. }

huangapple
  • 本文由 发表于 2015年11月26日 05:21:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/33926629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定