Skip to content

Instantly share code, notes, and snippets.

@iporsut
Last active June 11, 2023 12:57
Show Gist options
  • Save iporsut/12e075eb22555575d76aef6ae1350f8d to your computer and use it in GitHub Desktop.
Save iporsut/12e075eb22555575d76aef6ae1350f8d to your computer and use it in GitHub Desktop.
Go Back to Basics: Slice

How to declare slice variable

        var nums []int

What's zero value of slice variable

        var nums []int

        fmt.Println(nums) // []
        fmt.Println(nums == nil) // true

How to initial slice variable with slice literal

        nums := []int{1, 2, 3, 4, 5}
        fmt.Println(nums) // [1 2 3 4 5]

        nums := []int{}
        fmt.Println(nums) // []
        fmt.Println(nums == nil) // false

How to initial slice variable with make function

        nums := make([]int, 0)
        fmt.Println(nums) // []

        nums := make([]int, 5)
        fmt.Println(nums) // [0 0 0 0 0]

        nums := make([]int, 0, 5)
        fmt.Println(nums) // []

How to count elements in slice

        nums := []int{1, 2, 3, 4, 5}
        fmt.Println(len(nums)) // 5

How to append an element to slice

        nums := []int{}
        nums = append(nums, 1)
        nums = append(nums, 2)
        nums = append(nums, 3)
        nums = append(nums, 4)
        nums = append(nums, 5)
        fmt.Println(nums) // [1 2 3 4 5]

        nums = append(nums, 6, 7, 8, 9, 10)
        fmt.Println(nums) // [1 2 3 4 5 6 7 8 9 10]

How to append all elements from other slice to slice

        nums := []int{}
        nums = append(nums, 1)
        nums = append(nums, 2)
        nums = append(nums, 3)
        nums = append(nums, 4)
        nums = append(nums, 5)
        fmt.Println(nums) // [1 2 3 4 5]

        otherNums := []int{6, 7, 8, 9, 10}
        nums = append(nums, otherNums...)
        fmt.Println(nums) // [1 2 3 4 5 6 7 8 9 10]

How to loop to access each element in slice

	nums := []int{1, 2, 3, 4, 5}
	for i := 0; i < len(nums); i++ {
		fmt.Println(nums[i])
	}
        // Output
        // 1
        // 2
        // 3
        // 4
        // 5

        nums := []int{1, 2, 3, 4, 5}
        for i := range nums {
                fmt.Println(nums[i])
        }
        // Output
        // 1
        // 2
        // 3
        // 4
        // 5

        nums := []int{1, 2, 3, 4, 5}
        for _, v := range nums {
                fmt.Println(v)
        }
        // Output
        // 1
        // 2
        // 3
        // 4
        // 5

        nums := []int{1, 2, 3, 4, 5}
        for i, v := range nums {
                fmt.Printf("index %d: %d\n", i, v)
        }
        // Output
        // index 0: 1
        // index 1: 2
        // index 2: 3
        // index 3: 4
        // index 4: 5

How to slice a slice (sub slice)

        nums := []int{1, 2, 3, 4, 5}
        nums = nums[1:3] // [x:y] => x จนถึง (y-1)
        fmt.Println(nums) // [2 3]

        nums := []int{1, 2, 3, 4, 5}
        nums = nums[3:]
        fmt.Println(nums) // [4 5]

        nums := []int{1, 2, 3, 4, 5}
        nums = nums[:2]
        fmt.Println(nums) // [1 2]

        nums = nums[:]
        fmt.Println(nums) // [1 2 3 4 5]

How to slice a string

        phoneNumber := "0861234567"
        phoneNumber = phoneNumber[:3]
        fmt.Println(phoneNumber) // 086

        phoneNumber := "0861234567"
        phoneNumber = phoneNumber[:3] + "xxx" + phoneNumber[6:]
        fmt.Println(phoneNumber) // 086xxx4567

How to convert between slice of byte and string

        // Assume this data is read from `func ReadFile(name string) ([]byte, error)`
        fileData := []byte{72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100}
        msg := string(fileData)
        fmt.Println(msg) // Hello World

        msg := "Hello World"
        fileData := []byte(msg) // `func Write([]byte) (int, error)`
        fmt.Println(fileData) // [72 101 108 108 111 32 87 111 114 108 100]

How to copy slice

                srcSlice := []int{1, 2, 3, 4, 5} // No: dstSlice = srcSlice
                dstSlice := make([]int, 3)
                copy(dstSlice, srcSlice)
                fmt.Println(dstSlice) // [1 2 3]

                srcSlice := []int{1, 2, 3, 4, 5} // No: dstSlice = srcSlice
                var dstSlice []int
                dstSlice = append(dstSlice, srcSlice[:3]...)
                fmt.Println(dstSlice) // [1 2 3]

How to sort slice

        nums := []int{5,1,2,4,3}
        sort.Ints(nums)
        fmt.Println(nums) // [1 2 3 4 5]

        nums := []int{5,1,2,4,3}
        sort.Slice(nums, func(i, j int) bool {
                return nums[i] > nums[j]
        })
        fmt.Println(nums) // [5, 4, 3, 2, 1]

How to find element in slice

        nums := []int{1,2,3,4,5}
        found := false
        element := 3
        for _, v := range nums {
                if v == element {
                        found = true
                        break
                }
        }
        if found {
                fmt.Println("Found 3 in nums")
        }

How to filter slice

        nums := []int{1, 2, 3, 4, 5, 6}
        evenNums := []int{} // or just `var evenNums []int` or `evenNums := make([]int, 0)

        for _, v := range nums {
                if v % 2 == 0 {
                        evenNums = append(evenNums, v)
                }
        }

        fmt.Println(evenNums) // [2 4 6]

How to make slice of struct.

        type Todo struct {
                ID string
                Description string
                Done bool
        }

        todos := []Todo{
                {
                        ID: "1",
                        Description: "ซักผ้า",
                },
                {
                        ID: "2",
                        Description: "ล้างจาน",
                },
        }
        fmt.Println(todos)

        // เปลี่ยน Done ทั้งหมดเป็น true แบบนี้ไม่ work
        for _, v := range todos {
                v.Done = true
        }
        fmt.Println(todos) // [{1 ซักผ้า false} {2 ล้างจาน false}]

        // ต้องใช้แบบนี้
        for i := range todos {
                todos[i].Done = true
        }
        fmt.Println(todos) // [{1 ซักผ้า true} {2 ล้างจาน true}]

        // หรือเปลี่ยนเป็นเก็บ slice ของ pointer ของ Todo แทน
        todos := []*Todo{
                {
                        ID: "1",
                        Description: "ซักผ้า",
                },
                {
                        ID: "2",
                        Description: "ล้างจาน",
                },
        }

        for _, v := range todos {
                v.Done = true
        }
        fmt.Println(todos) // [0xc0000161b0 0xc0000161e0]
        for _, v := range todos {
                fmt.Println(*v)
        }
        // Output
        // {1 ซักผ้า true}
        // {2 ล้างจาน true}

Experimental Generic slice functions

https://pkg.go.dev/golang.org/x/exp/slices

Lodash for Go

https://github.com/samber/lo

Homework make command line TODO app and save it to CSV file.

todos.csv

ID, Description, Done
1, ซักผ้า, Yes
2, ล้างจาน, No
  1. Add Todo item ใหม่
  2. Mark as Done
  3. Filter only Done
  4. Filter only not Done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment