How to create a three-dimensional array in Golang

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

How to create a three-dimensional array in Golang

问题

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

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

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

有什么建议吗?

英文:

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.

func generateTiles(x int, y int, z int) [][][]*tile{
  var tiles [][][]*tile
  
  // Something here
  // resulting in a x by y by z array
  // filled with *tile
  
  return tiles
}

Any suggestions?

答案1

得分: 17

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

tiles := make([][][]*tile, x)

for i := range tiles {
    tiles[i] = make([][]*tile, y)
    for j := range tiles[i] {
        tiles[i][j] = make([]*tile, z)
    }
}

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

英文:

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

tiles = make([][][]*tile, x)

for i := range tiles {
	tiles[i] = make([][]*tile, y)
	for j := range tiles[i] {
		tiles[i][j] = make([]*tile, z)
	}
}

答案2

得分: 8

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

type Tile struct {
    x, y, z int
}

type Tiles struct {
    t       []*Tile
    w, h, d int
}

func New(w, h, d int) *Tiles {
    return &Tiles{
        t: make([]*Tile, w*h*d),
        w: w,
        h: h,
        d: d,
    }
}

// indexing based on http://stackoverflow.com/a/20266350/145587
func (t *Tiles) At(x, y, z int) *Tile {
    idx := t.h*t.w*z + t.w*y
    return t.t[idx+x]
}

func (t *Tiles) Set(x, y, z int, val *Tile) {
    idx := t.h*t.w*z + t.w*y
    t.t[idx+x] = val
}

func fillTiles(w int, h int, d int) *Tiles {
    tiles := New(w, h, d)

    for x := 0; x < w; x++ {
        for y := 0; y < h; y++ {
            for z := 0; z < d; z++ {
                tiles.Set(x, y, z, &Tile{x, y, z})
            }
        }
    }

    return tiles
}

playground

英文:

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

type Tile struct {
x, y, z int
}
type Tiles struct {
t       []*Tile
w, h, d int
}
func New(w, h, d int) *Tiles {
return &amp;Tiles{
t: make([]*Tile, w*h*d),
w: w,
h: h,
d: d,
}
}
// indexing based on http://stackoverflow.com/a/20266350/145587
func (t *Tiles) At(x, y, z int) *Tile {
idx := t.h*t.w*z + t.w*y
return t.t[idx+x]
}
func (t *Tiles) Set(x, y, z int, val *Tile) {
idx := t.h*t.w*z + t.w*y
t.t[idx+x] = val
}
func fillTiles(w int, h int, d int) *Tiles {
tiles := New(w, h, d)
for x := 0; x &lt; w; x++ {
for y := 0; y &lt; h; y++ {
for z := 0; z &lt; d; z++ {
tiles.Set(x, y, z, &amp;Tile{x, y, z})
}
}
}
return tiles
}

<kbd>playground</kbd>

答案3

得分: 0

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

以下是我编写的代码:

package main

import (
	"fmt"
)

type Tile struct {
	value int
}

func create3D(x, y, z int) [][][]*Tile {
	result := make([][][]*Tile, x)
	for i := 0; i < x; i++ {
		result[i] = make([][]*Tile, y)
		for j := 0; j < y; j++ {
			result[i][j] = make([]*Tile, z)
			for k := 0; k < z; k++ {
				result[i][j][k] = new(Tile)
				result[i][j][k].value = i + j + k
			}
		}
	}
	return result
}

func main() {
	X := 3
	Y := 4
	Z := 5

	mat := create3D(X, Y, Z)
	for i := 0; i < X; i++ {
		for j := 0; j < Y; j++ {
			for k := 0; k < Z; k++ {
				fmt.Printf("%d ", mat[i][j][k].value)
			}
			fmt.Println()
		}
		fmt.Println()
	}

}

希望对你有帮助!

英文:

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

package main
import (
&quot;fmt&quot;
)
type Tile struct {
value int
}
func create3D( x, y, z int) [][][]*Tile {
result := make([][][]*Tile,x)
for i := 0 ; i &lt; x ; i++ {
result[i] = make([][]*Tile,y);
for j := 0; j &lt; y; j++ {
result[i][j] = make([]*Tile,z);
for k := 0 ; k &lt; z; k++ {
result[i][j][k] = new(Tile)
result[i][j][k].value = i + j + k;
}
}
}
return result
}
func main() {
X := 3
Y := 4
Z := 5
mat := create3D( X , Y , Z);
for i := 0; i &lt; X; i++ {
for j := 0 ; j &lt; Y; j++ {
for k := 0 ; k &lt; Z; k++ {
fmt.Printf(&quot;%d &quot;,mat[i][j][k].value)
}
fmt.Println();
}
fmt.Println();
}
}

答案4

得分: -1

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

func generateTiles(x int, y int, z int) [][][]*tile {
    var tiles [][][]*tile

    for i := 0; i < z; i++ {
        var layer [][]*tile
        for j := 0; j < y; j++ {
            var row []*tile
            for k := 0; k < x; k++ {
                var t *tile
                t = &tile{}
                row = append(row, t)
                count++
            }
            layer = append(layer, row)
        }
        tiles = append(tiles, layer)
    }

    return tiles
}
英文:

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.

func generateTiles(x int, y int, z int) [][][]*tile {
var tiles [][][]*tile
for i := 0; i &lt; z; i++ {
var layer [][]*tile
for j := 0; j &lt; y; j++ {
var row []*tile
for k := 0; k &lt; x; k++ {
var t *tile
t = &amp;tile{}
row = append(row, t)
count++
}
layer = append(layer, row)
}
tiles = append(tiles, layer)
}
return tiles
}

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:

确定