Table of Contents
Open Table of Contents
Pengenalan
Algoritma adalah langkah atau tahapan untuk menyelesaikan persoalan, jadi bisa di katakan algoritma seseorang dalam menyelesaikan masalah itu dapat berbeda-beda, pada postingan ini akan membahas data struktur terlebih dulu yang harapannya bisa dikembangkan lebih lanjut oleh diri kita, ibaratnya seperti mempelajari operasi penjumlahan, pengurangan, perkalian dan pembagian, operasi tersebut merupakan dasar dari cara seseorang menyelesaikan permasalahan matematika.
Agar lebih mudah mengerti algoritma yang sudah ada, saya coba untuk belajar dan mengulas kembali pada bagian struktur data, jadi ada cukup banyak struktur data yang saya pelajari, seperti pada postingan ini terdapat array, slice, map, struct untuk penjelasan dan contohnya saya uraikan di bawah ini
Data Structure
Array
Sering disebut sebagai kumpulan dari item atau elemen yang memiliki tipe sama (homogen),
- Bagaimana array digunakan?
- Menyimpan data yang di proses
- Melakukan implementasi Stack dan Queue
- Representasi data ke dalam tabel dan matriks
- Membuat data struktur yang dinamis seperti linked list dan tree
- Operasi pada Array Karena go sangat strict dengan tipe data dan struktur data, kita tidak dapat leluasa manipulasi array seperti menambahkan elemen, menghapus elemen pada go, tetapi menurut saya ini menjadi nilai tambah karena menjadi lebih konsisten, berikut cara untuk inisialisasi array pada go, mengubah nilai dari indeks tertentu, dan melakukan iterasi pada array
Inisialisasi Array dan mengubah nilai elemen pada array
Pada Go dalam melakukan inisialisasi array dapat dilakukan dengan dua cara yaitu:
- inisialisasi langsung simpan elemen
- inisialisasi definisi elemen by index Lalu untuk pengoperasian seperti memanggil array, atau mengambil elemen pada array serupa dengan bahasa pemrograman pada python, cukup panggil array beserta indexnya
// inisialisasi array dan mengganti item
package main
import "fmt"
func main() {
// inisialisasi array cara 1
kardus := [4]string{"Pisang", "Susu", "Sendok", "Botol"}
// inisialisasi array cara 2
var kumpulan_data [4]int
kumpulan_data[0] = 3
kumpulan_data[1] = 4
kumpulan_data[2] = 5
kumpulan_data[3] = 6
// mengganti nilai array
kardus[2] = "Garpu"
kumpulan_data[0] = 1
// cetak array
fmt.Println(kardus)
fmt.Println(kumpulan_data)
fmt.Println("elemen pada kardus indeks ke-2:", kardus[0:3])
fmt.Println("elemen pada kumpulan_data indeks ke-0:", kumpulan_data[0])
}
output:
[Pisang Susu Garpu Botol]
[1 4 5 6]
elemen pada kardus indeks ke-2: [Pisang Susu Garpu]
elemen pada kumpulan_data indeks ke-0: 1
Iterasi pada array
Untuk menyebutkan elemen pada array secara berulang dapat dilakukan dengan cara looping, dapat dengan dua cara yaitu:
- for loop
- for … range
// iterasi array sequential
package main
import "fmt"
func main() {
kardus := [4]string{"Pisang", "Susu", "Sendok", "Botol"}
for i := 0; i < len(kardus); i++ {
fmt.Println(kardus[i])
}
}
output:
Pisang
Susu
Sendok
Botol
Jika iterasi menggunakan for… range maka memiliki dua argumen yang akan di bawa saat iterasi yaitu indeks dan value, jika hanya memberikan satu argumen maka return nya adalah nilai indeksnya
// / iterasi array sequential menggunakan range
package main
import "fmt"
func main() {
kardus := [4]string{"Pisang", "Susu", "Sendok", "Botol"}
//dua argumen (index, value)
for index, value := range kardus {
fmt.Println(index, value)
}
fmt.Println("============")
//satu argumen
for index := range kardus {
fmt.Println(kardus[index])
}
}
output:
0 Pisang
1 Susu
2 Sendok
3 Botol
============
Pisang
Susu
Sendok
Botol
Untuk melakukan reverse pada elemen array dapat menggunakan cara berikut, singkatnya i = 0, j = len(s)-1
untuk melakukan penukaran elemen, pada go dapat dilakukan dengan cara s[i], s[j] = s[j], s[i]
artinya s[i] = s[j], s[j] = s[i]
package main
import "fmt"
func main() {
s := [4]string{"Pisang", "Susu", "Sendok", "Botol"}
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
fmt.Println(s)
}
output:
[Botol Sendok Susu Pisang]
Lalu untuk memanggil elemen pada array secara reverse dapat dilakukan for loop dengan iterasi menurun (decrement)
// iterasi array reverse
package main
import "fmt"
func main() {
kardus := [4]string{"Pisang", "Susu", "Sendok", "Botol"}
for i := len(kardus) - 1; i >= 0; i-- {
fmt.Println(kardus[i])
}
}
output:
Botol
Sendok
Susu
Pisang
Slice
Pada go slice merupakan struktur data yang lebih fleksibel dibandingkan dengan array, karena tidak perlu mendefinisikan panjang elemennya, hanya dengan hal itu kita dapat melakukan banyak operasi pada slice seperti menambahkan elemen, menghapus elemen, dan memanipulasi elemen lebih mudah, tetapi karena kemudahannya terkadang slice dapat menjadi tidak konsisten dibandingkan array
Slice dapat melakukan operasi pengambilan data dari array yang disimpan ke dalam suatu koleksi yang dinamis, jadi mudahnya, slice itu mengambil data dari array dan disimpan sebagai koleksi yang dinamis (ukurannya dapat bertambah atau berkurang), kita akan coba membuat slice, dan melakukan manipulasi slice, untuk iterasi slice sama seperti pada array.
Membuat Slice
package main
import "fmt"
func main() {
//inisialisasi array
prima := [8]int{2, 3, 5, 7, 11, 13, 17, 19}
// melakukan slicing elemen array dan disimpan dalam slice
primaSlice := prima[:5]
fmt.Println(prima) //output array
fmt.Println(primaSlice) //output slice
}
Output:
[2 3 5 7 11 13 17 19]
[2 3 5 7 11]
Dalam Go kita dapat membuat slice dengan fungsi make
fungsi tersebut membutuhkan dua parameter wajib (tipe data dan panjang slice) dan satu parameter opsional (kapasitas), kapasitas digunakan untuk slice memesan alokasi memori pada sistem kita, jika kita melakukan input lebih dari kapasitas maka slice akan melakukan alokasi memori ulang sebesar jumlah kapasitas slice saat itu.
package main
import "fmt"
func main() {
slice1 := make([]bool, 3) // capacity = 0
slice2 := make([]int, 3, 5) // menambahkan capacity=5
fmt.Println(slice1)
fmt.Println(slice2)
}
Output:
[false false false]
[0 0 0]
Jika kita memasukkan argumen length lebih besar dibandingkan argumen capacity maka akan menampilkan error pada output yang menyatakan argumen length dan capacity kebalik, seperti pada kode di bawah ini
package main
import "fmt"
func main() {
slice2 := make([]int, 6, 5) // menambahkan length=6 capacity=5
fmt.Println(slice2)
}
Output:
invalid argument: length and capacity swapped
Baris kode berikut ini juga termasuk cara untuk membuat slice
package main
import "fmt"
func main() {
var prima []int
prima = []int{2, 3, 5, 7, 9, 11, 13, 19}
fmt.Println(prima)
}
Manipulasi Slice
Untuk melakukan manipulasi serupa dengan array, tetapi karena slice memiliki panjang yang dinamis disini kita dapat menggunakan fungsi append
untuk menambahkan elemen pada slice
package main
import "fmt"
func main() {
var slice1 []int
slice1 = []int{2, 3, 5, 7, 9, 11, 13, 19}
slice2 := make([]bool, 3, 5) // output: [false, false, false]
// menambahkan elemen pada slice
slice1 = append(slice1, 23, 29)
slice2 = append(slice2, false, true)
// mengganti elemen pada slice
slice2[0] = true
fmt.Println(slice1)
fmt.Println(slice2)
}
Output:
[2 3 5 7 9 11 13 19 23 29]
[true false false false true]
Map
Map merupakan tipe struktur data yang berbentuk key dan value seperti object pada JavaScript dan dictionary pada python, key dapat dikatakan sebagai identifier sehingga harus bersifat unik dengan tipe data yang bebas, untuk nilai default dari variabel map adalah nil
maka harus di inisialisasi
Membuat Map
Untuk membuat map terdapat tiga cara tetapi bisa saja dengan variasi yang berbeda, caranya antara lain:
- deklarasi lalu inisialisasi terpisah, untuk cara pertama deklarasi variable map lalu dipisahkan inisialisasinya
package main
import "fmt"
func main() {
var stokBuah map[string]int //deklarasi tipe data untuk key dan value
stokBuah = map[string]int{}
fmt.Println(stokBuah)
}
- inisialisasi secara eksplisit, untuk cara ini deklarasi variable map dan inisialisasi di gabung dalam satu baris.
package main
import "fmt"
func main() {
stokSayur := map[string]int{}
fmt.Println(stokSayur)
}
- Menggunakan
make
, kelebihan menggunakanmake
adalah alokasi memorinya, dengan menggunakanmake
maka memori akan di reservasi untuk membuat map kosong yang akan ditugaskan nanti.
package main
import "fmt"
func main() {
stokDaging := make(map[string]int) //deklarasi tipe data untuk key dan value
stokDaging["ayam"] = 400
stokDaging["sapi"] = 300
fmt.Println(stokDaging)
}
Menambahkan dan Mengakses Nilai
Untuk menambahkan atau mengisi nilai map terdapat 2 cara yang dapat dilakukan, yaitu dengan cara key-value pairs dan objek literal
package main
import "fmt"
func main() {
// 1. key-value pairs
var stokBuah map[string]int //deklarasi tipe data untuk key dan value
stokBuah = map[string]int{} //inisialisasi map
stokBuah["mangga"] = 40
stokBuah["pisang"] = 30
stokBuah["melon"] = 14
fmt.Println(stokBuah)
fmt.Println("akses nilai mangga: ", stokBuah["mangga"])
//2. objek literal
stokSayur := map[string]int{
"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45,
}
fmt.Println(stokSayur)
fmt.Println("akses nilai kol: ", stokSayur["kol"])
//khusus. untuk make menggunakan key-value pairs
stokDaging := make(map[string]int) //deklarasi tipe data untuk key dan value
stokDaging["ayam"] = 400
stokDaging["sapi"] = 300
fmt.Println(stokDaging)
fmt.Println("akses nilai sapi: ", stokDaging["sapi"])
}
output:
map[mangga:40 melon:14 pisang:30]
akses nilai mangga: 40
map[buncis:30 kol:33 selada:45 tauge:42]
akses nilai kol: 33
map[ayam:400 sapi:300]
akses nilai sapi: 300
Membuat Nested Map
Untuk membuat nested map maka diperlukan inisialisasi map sebanyak n, jika ingin nested menjadi dua map maka inisialisasi sebanyak 2.
package main
import "fmt"
func main() {
stokDagang := map[string]map[string]int{
"sayuran": {"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45},
"daging": {"ayam": 500,
"sapi": 300},
}
fmt.Println(stokDagang)
fmt.Println("akses nilai sayuran: ", stokDagang["sayuran"])
fmt.Println("akses nilai daging: ", stokDagang["daging"])
fmt.Println("akses nilai kol: ", stokDagang["sayuran"]["kol"])
fmt.Println("akses nilai sapi: ", stokDagang["daging"]["sapi"])
}
output:
map[daging:map[ayam:500 sapi:300] sayuran:map[buncis:30 kol:33 selada:45 tauge:42]]
akses nilai sayuran: map[buncis:30 kol:33 selada:45 tauge:42]
akses nilai daging: map[ayam:500 sapi:300]
akses nilai kol: 33
akses nilai sapi: 300
Iterasi Item Map
untuk melakukan iterasi item sebenarnya sama seperti sebelumnya, selagi paham cara akses map maka iterasi dapat dilakukan, untuk saat ini kita coba iterasikan menggunakan for-range
kita akan coba lakukan iterasi untuk map biasa dan nested map.
- Iterasi Map
package main
import "fmt"
func main() {
stokSayur := map[string]int{
"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45,
}
for key, value := range stokSayur {
fmt.Println(key, value)
}
}
output:
buncis 30
tauge 42
kol 33
selada 45
- Iterasi Nested Map, pada nested map iterasi yang dilakukan sebanyak nesting yang dilakukan
package main
import "fmt"
func main() {
stokDagang := map[string]map[string]int{
"sayuran": {"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45},
"daging": {"ayam": 500,
"sapi": 300},
}
for category, items := range stokDagang {
fmt.Println("----------------")
fmt.Println(category, ":")
for item, quantity := range items {
fmt.Println(item, quantity)
}
}
}
output:
----------------
sayuran :
buncis 30
tauge 42
kol 33
selada 45
----------------
daging :
sapi 300
ayam 500
Cek key yang sudah ada
Karena go dapat melakukan multiple return values maka kita bisa manfaatkan hal tersebut untuk melakukan pengecekan, cara kerja metode tersebut cukup mudah, kita hanya perlu assign dua variable maka masing-masing variable akan mengembalikan nilainya, karena saat memanggil map akan membawa dua nilai yaitu nilai key dan statusnya (true atau false) maka variable akan mengembalikan kedua nilai tersebut.
package main
import "fmt"
func main() {
stokSayur := map[string]int{
"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45,
}
fmt.Println(stokSayur)
fmt.Println("akses nilai kol: ", stokSayur["kol"])
// cek elemen map
//jika ada elemen
element, status := stokSayur["selada"]
fmt.Println(element, status)
//jika tidak ada elemen
element, status = stokSayur["bayam"]
fmt.Println(element, status)
//jika tidak perlu element masukkan blank identifier _
_, status = stokSayur["kol"]
fmt.Println(status)
}
output:
map[buncis:30 kol:33 selada:45 tauge:42]
akses nilai kol: 33
45 true
0 false
Pada kode diatas dilakukan assign variable element dan status ke map tertentu, map akan mengembalikan dua nilai yaitu value dari key dan statusnya, jika elemen pada map stokSayur["selada"]
ada maka akan mengembalikan value dari key “selada” dan statusnya true
. jika tidak ingin mengembalikan salah satunya (element atau status) maka dapat diisikan salah satu variablenya dengan blank_identifier.
Memperbaharui Nilai
Untuk melakukan pembaharuan nilai sama seperti slice dan array kita panggilkan key yang ingin di pembaharui lalu assign dengan nilai terbaru
package main
import "fmt"
func main() {
stokSayur := map[string]int{
"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45,
}
fmt.Println(stokSayur)
fmt.Println("akses nilai selada: ", stokSayur["selada"])
//melakukan update key selada
stokSayur["selada"] = 25
fmt.Println(stokSayur)
fmt.Println("akses nilai selada: ", stokSayur["selada"])
}
output:
map[buncis:30 kol:33 selada:45 tauge:42]
akses nilai selada: 45
map[buncis:30 kol:33 selada:25 tauge:42]
akses nilai selada: 25
Menghapus key
Untuk menghapus key beserta nilainya dapat gunakan function yang disediakan oleh Go yaitu delete
, function tersebut membutuhkan dua parameter yaitu delete(m map[[Type], key [Type]
, dimana m dengan tipe data map dan key dengan tipe datanya.
package main
import "fmt"
func main() {
stokSayur := map[string]int{
"buncis": 30,
"tauge": 42,
"kol": 33,
"selada": 45,
}
delete(stokSayur, "kol") //penghapusan key
fmt.Println(stokSayur)
//pengecekan key
element, status := stokSayur["kol"]
fmt.Println(element, status)
}
output:
map[buncis:30 selada:45 tauge:42]
0 false