# Slices of Slices of Slices in Go

- Published: September 10, 2013
- Author: William Kennedy
- URL: https://www.ardanlabs.com/blog/2013/09/slices-of-slices-of-slices-in-go.html

I am working on building code to load polygons for the different Marine Forecast areas in the United States. These polygons need to be stored in MongoDB and there is a special way that needs to be done. It would not have been a big deal if it wasn't for this fact. There isn't just one polygon for each area. There is an external polygon and then zero to many interior polygons that need to be stored in relationship.<br />
<br />
After staring at the problem for a bit I realized that I needed to create a slice of Marine Forecast areas, each of which contained a slice of polygons. To store each polygon ring I needed a slice of geographic coordinates. Finally each coordinate needed to be stored in a two dimensional array of floats.<br />
<br />
A picture is worth a thousand words:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">

<a href="../../../images/goinggo/Screen+Shot+2013-09-10+at+4.42.21+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"><span class="sr-only">View linked image: Screen Shot</span>![Screen Shot](../../../images/goinggo/Screen+Shot+2013-09-04+at+5.02.55+PM.png)</a>

</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
When the data is stored in MongoDB it needs to follow this data pattern:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">

<a href="../../../images/goinggo/Screen+Shot+2013-09-10+at+3.46.19+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"><span class="sr-only">View linked image: Screen Shot</span>![Screen Shot](../../../images/goinggo/Screen+Shot+2013-09-10+at+3.46.19+PM.png)</a>

</div>
<br />
My head is spinning just looking at the diagram and the picture. The diagram depicts how all the slices and objects need to be organized.<br />
<br />
The picture shows how the polygons need to be stored in MongoDB. There will be multiple elements under coordinates, each with its own set of points.<br />
<br />
I decided to build a test application to figure out how to structure and store the data.<br />
<br />
<div style="clear: both;">
</div>
The more I use slices the more I really love them. I love how I can pass them in and out of functions and not concern myself with handling references or how memory is being handled. A slice is a lightware data structure that can safely be copied in and out of functions.<br />
<br />
I catch myself thinking all the time that I need to pass a reference of the slice so a copy of the data structure is not made on the stack. Then I remember, the data structure is 24 bytes, I am not copying all the data that is abstracted underneath it.<br />
<br />
Read these two articles to learn more about slices:<br />
<br />
<a href="https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html" target="_blank"><span class="sr-only">External resource on ardanlabs.com: </span>https&#58;//www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html</a><br />
<a href="https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html" target="_blank"><span class="sr-only">External resource on ardanlabs.com: </span>https&#58;//www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html</a><br />
<br />
Let's look at the data structure that will hold and store the data for MongoDB:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
// Polygon defines a set of points that complete a ring<br />
// around a geographic area<br />
type Polygon [][2]float64<br />
<br />
// PolygonRings defines a MongoDB Structure for storing multiple polygon rings<br />
type PolygonRings struct {<br />
&nbsp; &nbsp; Type        string &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `bson:&quot;type&quot;`<br />
&nbsp; &nbsp; Coordinates []Polygon `bson:&quot;coordinates&quot;`<br />
}<br />
<br />
// Represents a marine station and its polygons<br />
type MarineStation struct {<br />
&nbsp; &nbsp; StationId string &nbsp; &nbsp; &nbsp;`bson:&quot;station_id&quot;`<br />
&nbsp; &nbsp; Polygons  PolygonRings `bson:&quot;polygons&quot;`<br />
}
</div>
<br />
The Polygon type represents a slice of 2 floating point numbers. This will represent each point that makes up the polygon.<br />
<br />
The PolygonRings structure takes on the MongoDB format required for storing polygons. If you want to use MongoDB to perform geospatial searches against the polygons this is required.<br />
<br />
The MarineStation structure simulates an individual station and the set of polygons associated with the station.<br />
<br />
The test code is going to create one station with two polygons. Then it will display everything. &nbsp;Let's look at how to create the slice of marine stations and create a single marine station for testing:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
// Create a nil slice to store the polygon rings<br />
// for the different marine stations<br />
var marineStations []MarineStation<br />
<br />
// Create a marine station for AMZ123<br />
marineStation := MarineStation{<br />
&nbsp; &nbsp; StationId: &quot;AMZ123&quot;,<br />
&nbsp; &nbsp; Polygons: PolygonRings{<br />
&nbsp; &nbsp; &nbsp; &nbsp; Type:        &quot;Polygon&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; Coordinates: []Polygon{},<br />
&nbsp; &nbsp; },<br />
}
</div>
<br />
The first line of code creates a nil slice that can hold MarineStation objects. Then we create a MarineStation object using a composite literal. Within the composite literal we have another composite literal to create an object of type PolygonRings for the Polygons property. Then within the creation of the PolygonRings object we create an empty slice that can hold Polygon objects for the Coordinates property.<br />
<br />
To learn more about composite literals check out this document:<br />
<br />
<a href="http://golang.org/ref/spec#Composite_literals" target="_blank"><span class="sr-only">External resource on golang.org: </span>http&#58;//golang.org/ref/spec#Composite_literals</a><br />
<br />
Now it is time to add a couple of polygons to the station:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
// Create the points for the first polygon ring<br />
point1 := [2]float64{-79.7291190729999, 26.9729398600001}<br />
point2 := [2]float64{-80.0799532019999, 26.9692689500001}<br />
point3 := [2]float64{-80.0803627959999, 26.970533371}<br />
point4 := [2]float64{-80.0810508729999, 26.975004196}<br />
point5 := [2]float64{-79.7291190729999, 26.9729398600001}<br />
<br />
// Create a polygon for this ring<br />
polygon := Polygon{point1, point2, point3, point4, point5}<br />
<br />
// Add the polygon to the slice of polygon coordinates<br />
marineStation.Polygons.Coordinates = append(marineStation.Polygons.Coordinates, polygon)
</div>
<br />
First we create five points. Notice the first and last point are identical. This completes the ring. Then we store all the points into a Polygon object, using a composite literal. Last, we append the Polygon object to the slice of Polygons for the marine station.<br />
<br />
Then we do it all over again so we have two polygons associated with this marine station:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
// Create the points for the second polygon ring<br />
point1 = [2]float64{-80.4370117189999, 27.7877197270001}<br />
point2 = [2]float64{-80.4376220699999, 27.7885131840001}<br />
point3 = [2]float64{-80.4384155269999, 27.7885131840001}<br />
point4 = [2]float64{-80.4370117189999, 27.7877197270001}<br />
<br />
// Create a polygon for this ring<br />
polygon = Polygon{point1, point2, point3, point4}<br />
<br />
// Add the polygon to the slice of polygon coordinates<br />
marineStation.Polygons.Coordinates = append(marineStation.Polygons.Coordinates, polygon)
</div>
<br />
This second polygon has four points instead of five. The last thing left to do is add the MarineStation object to the slice of stations and display everything:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
// Add the marine station<br />
marineStations = append(marineStations, marineStation)<br />
<br />
Display(marineStations)</div>
<br />
The display function uses the keyword range to iterator over all the slices:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
func Display(marineStations []MarineStation) {<br />
&nbsp; &nbsp; for _, marineStation := range marineStations {<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;\nStation: %s\n&quot;, marineStation.StationId)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; for index, rings := range marineStation.Polygons.Coordinates {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;Ring: %d\n&quot;, index)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for _, coordinate := range rings {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;Point: %f,%f\n&quot;, coordinate[0], coordinate[1])<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
}
</div>
<br />
The function takes a slice of MarineStation objects. Remember only the slice structure is being copied on the stack, not all the objects the slice represents.<br />
<br />
When we iterate through the slice of MarineStation objects and all the internal slices that make up the object, we get the following result:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
Station: AMZ123<br />
Ring: 0<br />
Point: -79.729119,26.972940<br />
Point: -80.079953,26.969269<br />
Point: -80.080363,26.970533<br />
Point: -80.081051,26.975004<br />
Point: -79.729119,26.972940<br />
Ring: 1<br />
Point: -80.437012,27.787720<br />
Point: -80.437622,27.788513<br />
Point: -80.438416,27.788513<br />
Point: -80.437012,27.787720
</div>
<br />
Using slices to solve this problem is fast, easy and effective. I have placed a working copy of the test code in the Go Playground:<br />
<br />
<a href="http://play.golang.org/p/UYO2HIKggy" target="_blank"><span class="sr-only">External resource on play.golang.org: </span>http&#58;//play.golang.org/p/UYO2HIKggy</a><br />
<br />
Building this quick test application has shown me again how using slices has very real advantages. They will make you more productive and your code perform well. Not having to worry about memory management and handling references to pass data in and out of functions is huge. Take the time to learn how to use slices in your code, you will thank yourself later.<br />
<br />
