Menu
CoddyTech

Sao chép ánh xạ

Bài học 18 trên 21 trong khóa học Slice và map trong Go của Coddy.

Tương tự như cách chúng ta đã làm với lát cắt, ta có thể sao chép một map và thêm giá trị mới vào đó.

Hãy xem xét một map như sau:

products := map[string]int{
   "MacBook": 5000,
   "iPhone": 1000,
   "Vision pro": 3000,
}

Giả sử chúng ta cần sao chép map products:

list := products

Thao tác này sẽ tạo một bản sao của map products vào list. Tuy nhiên, vấn đề là những thay đổi trên một map sẽ ảnh hưởng đến map còn lại vì cả hai dùng chung một vùng nhớ. Ta có thể xác minh điều này bằng cách in địa chỉ bộ nhớ của chúng:

fmt.Printf("%p \n", list)
fmt.Printf("%p", products)

Đầu ra như sau:

0xc00010e0c0 
0xc00010e0c0

Giải pháp ở đây là dùng từ khóa make. Trước tiên, ta khai báo một map bằng từ khóa make:

list := make(map[string]int)

Bạn có thể thắc mắc, dùng make khác gì so với cách khai báo đơn giản như sau:

list := map[string]int{}

Thực ra, không có khác biệt nào, ngoại trừ việc dùng make cho phép ta đặt độ dài cho map.

list := make(map[string]int, len(products))

Ở đây, ta đặt độ dài bằng độ dài của map cần sao chép.

Lưu ý: Độ dài của map không giống như của lát cắt. Ngay cả khi đặt độ dài, ta vẫn có thể vượt quá giới hạn đó mà không gặp vấn đề gì.

Sau khi khai báo map mới, ta có thể dùng vòng lặp để sao chép các phần tử từ products sang map list:

list := make(map[string]int, len(products))
for key, value := range products {
   list[key] = value
}

Kết quả sẽ là:

map[Golang Book:400 Python Book:300 Rust Book:500]

Giờ đây, nếu ta thay đổi một map, thay đổi đó sẽ không ảnh hưởng đến map còn lại.
 

challenge icon

Thử thách

Dễ

Trong đoạn code đã cho, ta định nghĩa một ánh xạ sản phẩm có tên là productByName:

  • Tạo một ánh xạ mới có tên là productByPrice.
  • Sao chép các phần tử từ ánh xạ productByName, nhưng theo chiều ngược lại: price sẽ là khóa, còn name sẽ là giá trị.
  • In cả hai ánh xạ ra màn hình.

Tự làm thử

package main

import "fmt"

func main() {
    // Định nghĩa một map sản phẩm theo tên. Đừng thay đổi phần này!
    productByName := map[string]int{
        "MacBook":    5000,
        "iPhone":     1000,
        "Vision Pro": 3000,
    }

    // Tạo một map sản phẩm mới theo giá
    

    // Sao chép các phần tử từ productByName sang productByPrice
     

    // In cả hai map ra màn hình
    fmt.Println("By Name:", )
    fmt.Println("By Price:", )
}

Tất cả bài học trong Slice và map trong Go

Tự luyện tập: Trình biên dịch Go online