programing

지도를 복사하는 방법?

projobs 2021. 1. 19. 21:03
반응형

지도를 복사하는 방법?


amap다른 것 ( ) 안에 지도 ( ) 의 내용을 복사 한 다음 다음 반복 / 루프에서 새 값을 취할 수 있도록 aSuperMap지 웁니다 amap. 문제는 슈퍼 에서 참조를 지우지 않으면 지울 수 없다는 것입니다. 다음은 의사 코드입니다.

for something := range fruits{
        aMap := make(map[string]aStruct)
        aSuperMap := make(map[string]map[string]aStruct)

        for x := range something{
            aMap[x] = aData
            aSuperMap[y] = aMap
            delete(aMap, x)
    }
//save aSuperMap
  saveASuperMap(something)

}

나는 또한 일부 동적 인 것을 시도했지만 분명히 오류가 발생합니다 (nil에 할당 할 수 없음)

aSuperMap[y][x] = aData

문제는 연관 맵을 어떻게 만들 수 있습니까? PHP에서는 aSuperMap [y] [x] = aData를 사용합니다. golang에는 확실한 방법이없는 것 같습니다. delete(aMap, x)슈퍼 맵에서 참조를 삭제 하면 참조도 삭제됩니다. 삭제하지 않으면 수퍼 맵이 중복 데이터로 끝납니다. 기본적으로 각 루프 aMap에서 새 값과 모든 이전 값을 습니다.


지도를 복사하는 것이 아니라지도에 대한 참조입니다. 귀하는 delete따라서 원래의지도와 슈퍼지도 모두에서 값을 수정합니다. 지도를 복사하려면 다음 for과 같은 루프 를 사용해야합니다 .

for k,v := range originalMap {
  newMap[k] = v
}

다음은 현재 폐기 된 SO 문서의 예입니다.

// Create the original map
originalMap := make(map[string]int)
originalMap["one"] = 1
originalMap["two"] = 2

// Create the target map
targetMap := make(map[string]int)

// Copy from the original map to the target map
for key, value := range originalMap {
  targetMap[key] = value
}

지도 에서 발췌 -지도 복사 . 원저자는 JepZ였다 . 기여 세부 정보는 기여자 페이지 에서 확인할 수 있습니다 . 소스는 CC BY-SA 3.0에 따라 사용이 허가 되며 문서 아카이브 에서 찾을 수 있습니다 . 참조 주제 ID : 732 및 예제 ID : 9834.


딥 카피를 할 수 있도록 재귀를 사용 하고 그 자체 인 요소 map를 변경해야하는 경우를 대비해 나쁜 서프 시스를 피할 있습니다.mapmap

다음은 utils.go 의 예입니다 .

package utils

func CopyMap(m map[string]interface{}) map[string]interface{} {
    cp := make(map[string]interface{})
    for k, v := range m {
        vm, ok := v.(map[string]interface{})
        if ok {
            cp[k] = CopyMap(vm)
        } else {
            cp[k] = v
        }
    }

    return cp
}

그리고 테스트 파일 (예 : utils_test.go ) :

package utils

import (
    "testing"

    "github.com/stretchr/testify/require"
)

func TestCopyMap(t *testing.T) {
    m1 := map[string]interface{}{
        "a": "bbb",
        "b": map[string]interface{}{
            "c": 123,
        },
    }

    m2 := CopyMap(m1)

    m1["a"] = "zzz"
    delete(m1, "b")

    require.Equal(t, map[string]interface{}{"a": "zzz"}, m1)
    require.Equal(t, map[string]interface{}{
        "a": "bbb",
        "b": map[string]interface{}{
            "c": 123,
        },
    }, m2)
}

.NET map대신 다른 것으로 키가 필요한 경우 쉽게 읽을 수 있습니다 string.


개별 요소 복사, 간단한 예만으로도 저에게 효과적입니다.

maps := map[string]int {
    "alice":12,
    "jimmy":15,
}

maps2 := make(map[string]int)
for k2,v2 := range maps {
    maps2[k2] = v2
}

maps2["miki"]=rand.Intn(100)

fmt.Println("maps: ",maps," vs. ","maps2: ",maps2)

각 키 / 값 쌍을 수동으로 새 map. 이것은 사람들이 .NET Framework의 깊은 복사본을 원할 때마다 다시 프로그래밍해야하는 루프입니다 map.

다음을 사용 mapper하여 maps패키지 에서 설치하여 이에 대한 기능을 자동으로 생성 할 수 있습니다.

go get -u github.com/drgrib/maps/cmd/mapper

그리고 달리기

mapper -types string:aStruct

이는 파일을 생성합니다 map_float_astruct.go포함뿐만 아니라 (깊이) Copy지도뿐만 아니라 다른 "실종" map기능 ContainsKey, ContainsValue, GetKeys, 및 GetValues:

func ContainsKeyStringAStruct(m map[string]aStruct, k string) bool {
    _, ok := m[k]
    return ok
}

func ContainsValueStringAStruct(m map[string]aStruct, v aStruct) bool {
    for _, mValue := range m {
        if mValue == v {
            return true
        }
    }

    return false
}

func GetKeysStringAStruct(m map[string]aStruct) []string {
    keys := []string{}

    for k, _ := range m {
        keys = append(keys, k)
    }

    return keys
}

func GetValuesStringAStruct(m map[string]aStruct) []aStruct {
    values := []aStruct{}

    for _, v := range m {
        values = append(values, v)
    }

    return values
}

func CopyStringAStruct(m map[string]aStruct) map[string]aStruct {
    copyMap := map[string]aStruct{}

    for k, v := range m {
        copyMap[k] = v
    }

    return copyMap
}

전체 공개 : 나는이 도구의 작성자입니다. map다양한 유형 조합 을 위해 Go에 대해 이러한 알고리즘을 지속적으로 다시 작성했기 때문에이를 포함하는 패키지를 만들었습니다 .

참조 URL : https://stackoverflow.com/questions/23057785/how-to-copy-a-map

반응형