A slice of structures (golang)

Updated vegaseat 1 Tallied Votes 3K Views Share

Another little adventure into Go coding. This time a slice (a Go open ended array) of structures is used as a record for some data processing. For those who miss the ; at the end of a line of code, you can use them, but the lexer of the compiler will put them in for you. Go slices are simpler to work with and faster than traditional arrays, even though they use arrays as a backbone. Go was written for efficiency and speed of compilation in mind, it is intolerant of unused imports and unused variables. The reason you will see the blank identifier _ on occasion.

Note that in Go a multiline string is enclosed in ` (ascii 96, whatever those are called).

// slice_of_structs101.go
//
// convert a csv string into a slice of structures
//
// for imported package info see ...
// http://golang.org/pkg/fmt/
// http://golang.org/pkg/strconv/
// http://golang.org/pkg/strings/
//
// tested with Go version 1.4.2   by vegaseat  27apr2015

package main

import (
	"fmt"
	"strconv"
	"strings"
)

// structure fields match the csv file header
type Billionair struct {
	name   string
	wealth string
	age    string
	source string
}

// show the contents of a slice of strings one line at a time
func show_slice_str(slice []string) {
	for _, item := range slice {
		fmt.Println(item)
	}
}

func main() {
	fmt.Println("convert a csv string into a slice of structures:")

	// could come from a csv file generated by a spreadsheet
	// each line is name,wealth,age,source of a billionair
	csv_str := `Bill Gates,$79.2 billion,59,Microsoft
Carlos Slim,$77.1 billion,75,Telmex and Grupo Carso
Warren Buffett,$72.7 billion,84,Berkshire Hathaway
Amancio Ortega,$64.5 billion,78,Inditex Group
Larry Ellison,$54.3 billion,70,Oracle Corporation
Charles Koch,$42.9 billion,79,Koch Industries
David Koch,$42.9 billion,74,Koch Industries
Christy Walton,$41.7 billion,60,Wal-Mart
Jim Walton,$40.6 billion,66,Wal-Mart
Liliane Bettencourt,$40.1 billion,92,L'Oreal`

	fmt.Println("---------------------------------------------")
	fmt.Println("slice of strings ...")
	// first create a slice of all the lines in the csv_str
	// func Split(s, sep string) []string
	// returns a slice of substrings between sep separators
	slice_str := strings.Split(csv_str, "\n")

	fmt.Printf("%+v\n", slice_str[0])    // test
	fmt.Printf("type = %T\n", slice_str) // type = []string
	show_slice_str(slice_str)

	fmt.Println("---------------------------------------------")
	fmt.Println("slice of structures ...")
	// create pointer to an instance of structure Billionair
	pstb := new(Billionair)
	// now create a slice of structures	using the pointer
	slice_struct := make([]Billionair, len(slice_str))
	for ix, val := range slice_str {
		line := strings.Split(val, ",")
		//fmt.Println(line)
		pstb.name = line[0]
		pstb.wealth = line[1]
		pstb.age = line[2]
		pstb.source = line[3]
		slice_struct[ix] = *pstb
	}

	// %+v adds field names
	fmt.Printf("%+v\n", slice_struct[0])    // test
	fmt.Printf("type = %T\n", slice_struct) // type = []main.Billionair
	// show the contents of the slice of structures
	// range of a slice returns index, value pair
	// index not needed so use blank identifier _
	for _, item := range slice_struct {
		fmt.Println(item)
	}
	fmt.Println("---------------------------------------------")

	// process some data
	age_total := 0
	wealth_total := 0.0
	for _, item := range slice_struct {
		// convert string to integer
		age, err := strconv.Atoi(item.age)
		if err != nil {
			panic(err)
		}
		age_total += age
		// convert the numeric slice [1:5] of the string to a float64
		wealth, err := strconv.ParseFloat(slice_struct[0].wealth[1:5], 64)
		if err != nil {
			panic(err)
		}
		wealth_total += wealth
	}
	average_age := float64(age_total) / float64(len(slice_struct))
	fmt.Printf("average age  = %5.1f\n", average_age)
	fmt.Printf("total wealth = %5.1f billion\n", wealth_total)

	// extra stuff ...
	fmt.Println("---------------------------------------------")
	fmt.Println("extra tests ...")
	fmt.Printf("slice_struct[0].wealth = %v\n", slice_struct[0].wealth)
	// remove $ and billion
	fmt.Printf("slice_struct[0].wealth[1:5] = %v\n",
		slice_struct[0].wealth[1:5])
	// convert to a float
	wealth, err := strconv.ParseFloat(slice_struct[0].wealth[1:5], 64)
	// handle the error if there is one
	if err != nil {
		panic(err)
	}
	fmt.Printf("type = %T  value = %v\n", wealth, wealth)

}

/* result ...
convert a csv string into a slice of structures:
---------------------------------------------
slice of strings ...
Bill Gates,$79.2 billion,59,Microsoft
type = []string
Bill Gates,$79.2 billion,59,Microsoft
Carlos Slim,$77.1 billion,75,Telmex and Grupo Carso
Warren Buffett,$72.7 billion,84,Berkshire Hathaway
Amancio Ortega,$64.5 billion,78,Inditex Group
Larry Ellison,$54.3 billion,70,Oracle Corporation
Charles Koch,$42.9 billion,79,Koch Industries
David Koch,$42.9 billion,74,Koch Industries
Christy Walton,$41.7 billion,60,Wal-Mart
Jim Walton,$40.6 billion,66,Wal-Mart
Liliane Bettencourt,$40.1 billion,92,L'Oreal
---------------------------------------------
slice of structures ...
{name:Bill Gates wealth:$79.2 billion age:59 source:Microsoft}
type = []main.Billionair
{Bill Gates $79.2 billion 59 Microsoft}
{Carlos Slim $77.1 billion 75 Telmex and Grupo Carso}
{Warren Buffett $72.7 billion 84 Berkshire Hathaway}
{Amancio Ortega $64.5 billion 78 Inditex Group}
{Larry Ellison $54.3 billion 70 Oracle Corporation}
{Charles Koch $42.9 billion 79 Koch Industries}
{David Koch $42.9 billion 74 Koch Industries}
{Christy Walton $41.7 billion 60 Wal-Mart}
{Jim Walton $40.6 billion 66 Wal-Mart}
{Liliane Bettencourt $40.1 billion 92 L'Oreal}
---------------------------------------------
average age  =  73.7
total wealth = 792.0 billion
---------------------------------------------
extra tests ...
slice_struct[0].wealth = $79.2 billion
slice_struct[0].wealth[1:5] = 79.2
type = float64  value = 79.2
*/
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

IMHO, on the outside Go looks like C that has been modernized to fit present day requirements. Go handles concurrency and multiprocessing in a slick way.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

You can actually copy and paste Go code snippets into the online sandbox at
http://play.golang.org/
and run the code. You can edit the code and test your changes.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Just a beginner with Go, but I am having fun learning.
This snippet online play at:
http://play.golang.org/p/i54I8VpI4M

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.