Hemos trabajado en los conceptos anteriores con la estructura de datos tipo array. Un array es muy adecuado cuando conocemos antes de compilar el programa la cantidad de elementos a almacenar.
Hay muchas situaciones donde no sabemos cuantas componentes reservar para un array, en estas situaciones tenemos que utilizar probablemente slices.
Un slice permite almacenar un conjunto de datos del mismo tipo pero la cantidad de elementos de la misma puede crecer a lo largo de la ejecución del programa.
Confeccionar un programa que solicite al inicio cuantos importes de facturas se ingresaran por teclado. Almacenar los datos en un slice, imprimirlo y sumar todos sus elementos.
package main import "fmt" func main() { var cantidad int var suma float64 fmt.Print("Cuantas facturas se procesarán:") fmt.Scan(&cantidad) facturas := make([]float64, cantidad) for f :=0; f < len(facturas); f++ { fmt.Print("Ingrese importe de la factura:") fmt.Scan(&facturas[f]) suma = suma + facturas[f] } fmt.Println("Listado completo de facturas ingresadas") fmt.Println(facturas) fmt.Println("Importe total de todas las facturas:", suma) }
Hay varias formas de crear slices en el lenguaje Go. En este problema hemos creado el slice llamado facturas mediante la función make:
facturas := make([]float64, cantidad)
La función make en una de sus formas tiene dos parámetros, el primero indica el tipo de dato que almacena el slice y el segundo cuanto espacio se reserva. Pasamos la variable cantidad que será el número de facturas que ingresará el operador de nuestro programa.
Para acceder a las componentes de un slice es idéntico a como trabajamos con un array, es decir mediante un subíndice hacemos referencia a cada componente:
for f :=0; f < len(facturas); f++ { fmt.Print("Ingrese importe de la factura:") fmt.Scan(&facturas[f]) suma = suma + facturas[f] }
También mediante la función len podemos saber cuanto espacio tenemos reservado para el slice.
La función Println del paquete fmt muestra todo el contenido del slice:
fmt.Println("Listado completo de facturas ingresadas") fmt.Println(facturas)
Hay una función llamada append que añade al final una nueva componente al slice.
Emplear distintas formas para definr slices en Go.
package main import "fmt" func main() { var slice1 []int fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1)) slice1 = append(slice1, 100) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1)) slice1 = append(slice1, 200) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1)) slice1 = append(slice1, 300) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1)) slice2 := make ([]int, 2) slice2[0]=100 slice2[1]=200 slice2 = append(slice2, 300) fmt.Println("Elementos del slice2", slice2) fmt.Println("Cantidad de componentes del slice2", len(slice2)) slice3 := []int{100, 200} slice3 = append(slice3, 300) fmt.Println("Elementos del slice3", slice3) fmt.Println("Cantidad de componentes del slice3", len(slice3)) }
El resultado de ejecutar el programa es:
Podemos definir un slice vacío con la misma sintaxis que vimos para definir un array pero sin indicar entre corchetes la cantidad de elementos (esa diferencia de sintaxis le permite al compilador crear un slice o un array):
var slice1 []int
Si imprimimos el slice1 veremos corchetes abiertos y cerrados que nos indica que no tiene elementos y la función len nos retorna un cero:
fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1))
Mediante la función append podemos agregar una componente al final del slice, debemos pasar como parámetros el slice propiamente dicho y el valor a insertar. La función append retorna el slice modificado:
slice1 = append(slice1, 100) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1))
Como vemos al imprimir ahora el slice1 tiene un elemento con el valor 100 y la función len retorna un 1.
A medida que llamamos a la función append el slice1 crece:
slice1 = append(slice1, 200) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1)) slice1 = append(slice1, 300) fmt.Println("Elementos del slice1", slice1) fmt.Println("Cantidad de componentes del slice1", len(slice1))
La segunda forma de crear un slice y muy conveniente cuando sabemos de antemano cual será el tamaño inicial de slice es el empleo de la función make:
slice2 := make ([]int, 2) slice2[0]=100 slice2[1]=200 slice2 = append(slice2, 300) fmt.Println("Elementos del slice2", slice2) fmt.Println("Cantidad de componentes del slice2", len(slice2))
El slice2 se crea y reserva espacio para 2 enteros. Luego accedemos a sus elementos por medio de un subíndice. Si queremos en algún momento de nuestro programa que el slice2 siga creciendo llamamos de ahí en más a la función append.
Una tercer forma de crear un slice es en el momento que lo definimos indicar entre llaves los valores a almacenar, en nuestro ejemplo el slice3 reserva espacio para 2 elementos y lo carga con los valores 100 y 200:
slice3 := []int{100, 200}
También como en los casos anteriores si necesitamos más espacio podemos añadir mediante la llamada a la función append:
slice3 = append(slice3, 300) fmt.Println("Elementos del slice3", slice3) fmt.Println("Cantidad de componentes del slice3", len(slice3))
Confeccionar un programa que permita almacenar en dos slices los nombres de productos y sus precios (hacer que en las componentes de los mísmos subíndices se guarden datos relacionados)
Cuando inicia el programa solicitar la cantidad de productos a cargar.
Mostrar los datos de los dos slices
package main import "fmt" func main() { var cantidad int fmt.Print("Cuantos productos ingresará:") fmt.Scan(&cantidad) productos := make([]string, cantidad) precios := make([]float64, cantidad) for f := 0; f < len(productos); f++ { fmt.Print("Ingrese nombre del producto:") fmt.Scan(&productos[f]) fmt.Print("Ingrese el precio de dicho producto:") fmt.Scan(&precios[f]) } fmt.Println("Listado de todos los datos ingresados") for f := 0; f < len(productos); f++ { fmt.Println(productos[f], "-", precios[f]) } }
Un resultado particular de ejecutar este programa es:
Primero debe quedar claro que para resolver este problema necesitamos slices ya que el tamaño de las estructuras de datos variará en cada ejecución del programa (el operador puede ingresar cualquier cantidad de artículos)
Creamos dos slices llamados productos y precios, uno de tipo string y otro de tipo float64:
productos := make([]string, cantidad) precios := make([]float64, cantidad)
La cantidad de elementos de los slices depende del contenido de la variable cantidad.
Mediante un for recorremos y cargamos los dos slices y para que estén relacionados uno y el otro en las mismas posiciones de cada slice guardamos en uno el nombre del producto y en el slice paralelo su precio:
for f := 0; f < len(productos); f++ { fmt.Print("Ingrese nombre del producto:") fmt.Scan(&productos[f]) fmt.Print("Ingrese el precio de dicho producto:") fmt.Scan(&precios[f]) }
Queda finalmente mostrar los contenidos de los dos slices:
fmt.Println("Listado de todos los datos ingresados") for f := 0; f < len(productos); f++ { fmt.Println(productos[f], "-", precios[f]) }
ejercicio084.go package main import "fmt" func main() { var slice1 []int var valor int suma := 0 for { fmt.Print("Ingrese un entero (-1 para finalizar):") fmt.Scan(&valor) if valor==-1 { break } slice1 = append(slice1, valor) suma = suma + valor } promedio := suma / len(slice1) mayorProm := 0 for x := 0; x < len (slice1); x++ { if slice1[x] > promedio { mayorProm++ } } fmt.Println("El slice completo es") fmt.Println(slice1) fmt.Println("Promedio:", promedio) fmt.Println("La cantidad de valores mayores al promedio son:", mayorProm) }