Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a three-dimensional array in Golang

Tags:

arrays

go

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?

like image 995
Patrick Avatar asked Nov 25 '15 21:11

Patrick


2 Answers

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)
    }
}
like image 192
nemo Avatar answered Sep 29 '22 05:09

nemo


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 &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

like image 26
OneOfOne Avatar answered Sep 29 '22 04:09

OneOfOne