How to Create a Deep Copy of a Map and Clearing the Original Map in Go

In the Go programming language, a map is a reference type, which means that if you assign one map to another, both refer to the same underlying data. Therefore, changes to one map will reflect in the other. If you want to create a true “deep copy” of a map, you must do it manually by iterating over the original map and copying each key-value pair.

Creating a deep copy of a map and clearing the original map in Go involves “deep copying” and “clearing the map”. The “deep copy” process depends on the data types of the keys and values in the map.

Example 1

package main

import (
  "fmt"
)

func main() {
  originalMap := map[string][]int{
    "A": {1, 2},
    "B": {3, 4},
    "C": {5, 6},
  }

  copiedMap := deepCopyMap(originalMap)

  // Modify the original map and its values
  originalMap["D"] = []int{7, 8}
  originalMap["A"][0] = 42

  // Clear the original map
  clearMap(originalMap)

  // Print both maps to show that they are independent
  fmt.Println("Original map:", originalMap)
  fmt.Println("Copied map:", copiedMap)
}

func deepCopyMap(src map[string][]int) map[string][]int {
  dst := make(map[string][]int, len(src))
  for k, v := range src {
    dst[k] = make([]int, len(v))
    copy(dst[k], v)
  }
  return dst
}

func clearMap(m map[string][]int) {
  for k := range m {
    delete(m, k)
  }
}

Output

Original map: map[]

Copied map: map[A:[1 2] B:[3 4] C:[5 6]]

Example 2

package main

import (
  "fmt"
)

// Custom struct for the example
type Data struct {
  Value int
}

func main() {
  originalMap := map[string]*Data{
    "A": {Value: 1},
    "B": {Value: 2},
    "C": {Value: 3},
  }

 copiedMap := deepCopyMap(originalMap)

 // Modify the original map and its values
 originalMap["D"] = &Data{Value: 4}
 originalMap["A"].Value = 42

 // Clear the original map
 clearMap(originalMap)

 // Print both maps to show that they are independent
 fmt.Println("Original map:", originalMap)
 fmt.Println("Copied map:", copiedMap)
}

func deepCopyMap(src map[string]*Data) map[string]*Data {
  dst := make(map[string]*Data, len(src))
  for k, v := range src {
    // Create a new Data instance and copy the fields from the source value
    dataCopy := &Data{Value: v.Value}
    dst[k] = dataCopy
  }
  return dst
}

func clearMap(m map[string]*Data) {
  for k := range m {
    delete(m, k)
  }
}

Output

Original map: map[]

Copied map: map[A:0x14000096020 B:0x14000096028 C:0x14000096030]

This code used a custom struct Data as the map’s value type.

The deepCopyMap() function creates a new destination map and then iterates through each key-value pair in the source map.

Each key-value pair creates a new instance of the Data struct, copies the source struct’s fields to the new struct, and then assigns the new struct to the key in the destination map. This way, the destination map is a deep copy of the source map, and changes to the source map’s values won’t affect the copied map.

The clearMap() function iterates through all the keys in the map and removes them using the delete() built-in function, effectively clearing the map.

The main() function demonstrates the use of deepCopyMap() and clearMap() by creating an originalMap, deep copying it to copiedMap, modifying the original map and its values, and then clearing the original map.

The printed output shows that the two maps are independent, and changes to the original map don’t affect the copied map.

That’s it!

Leave a Comment