이동 중에 두 맵의 통합 얻기


81

파일 경로를 나타내는 개체를 만드는 재귀 함수가 있습니다 (키는 경로이고 값은 파일에 대한 정보입니다). 파일을 처리하기위한 목적 일 뿐이므로 재귀 적이므로 디렉토리가 발견되면 해당 함수가 디렉토리에서 재귀 적으로 호출됩니다.

즉, 두 맵 (즉, 재귀 호출의 값으로 업데이트 된 "메인"맵)에서 집합 공용체에 해당하는 작업을 수행하고 싶습니다. 하나의 맵을 반복하고 각 키, 값을 다른 맵의 동일한 것에 할당하는 것 외에 이것을 수행하는 관용적 인 방법이 있습니까?

즉 : 주어진는 a,b타입 인 map [string] *SomeObjectab갱신 할 방법이 결국 채워집니다 a의 값을 모두와 함께가 b?


2
아마 당신은 이런 종류의 작업에 대한 실제 세트 컨테이너를 이용할 수있다 : github.com/deckarep/golang-set
랄프 Caraveo에게

Ralph의 제안은 세트에 좋습니다. 그러나 나는 당신의 경우에 그것이 합병 이기 때문에 결합 이 아니라고 말할 것입니다 . 집합은 "키"의 모음이어야하며, 키-값 쌍의 모음은 두 개 여야합니다. 여기서 하나의 "집합"은 다른 "집합"보다 우선 순위를 가져야합니다.
ANisus 2014 년

답변:


132

내장 된 방식이나 표준 패키지에 이러한 병합을 수행하는 방법이 없습니다.

idomatic 방식은 단순히 반복하는 것입니다.

for k, v := range b {
    a[k] = v
}

5
ANisus의 답변에 추가하려면 : 맵은 본질적으로 해시 테이블입니다. 두 맵을 단순히 반복하는 것보다 두 맵의 합집합을 더 빠르게 계산할 수있는 방법은 없을 것입니다.
fuz 2014 년

리플렉션을 사용하여 유형에 구애받지 않는 통합 함수를 작성할 수 있지만 속도가 느립니다.
Evan

이 코드는 v를 a [k]에 할당하기 전에 a [k]와 v의 값을 합쳐야하지 않습니까? a [k]와 v가 배열이나 맵이라면 어떨까요?
vdolez

2
그는지도에있는 값이 아니라지도를 통합하려고합니다. 당신이 그런 일을하고 싶다면, 또는 그와 비슷한 것으로 바꾸면 a[k] = v됩니다 a[k] = a[k] + v.
Kyle

@Kyle 당신이 옳다고 생각합니다. 실제 공용체의 경우 다음을 사용할 수 있습니다.a[k] = append(a[k], v...)
user3405291

2

중첩 된지도 몇을 가지고있는 경우 leftright,이 함수는 재귀에서 항목을 추가 할 것이다 rightleft. 키가 이미 있으면 left구조로 더 깊이 재귀하고 키를 추가 하기 만 시도 합니다 left(예 : 절대로 대체하지 않음).


type m = map[string]interface{}

// Given two maps, recursively merge right into left, NEVER replacing any key that already exists in left
func mergeKeys(left, right m) m {
    for key, rightVal := range right {
        if leftVal, present := left[key]; present {
            //then we don't want to replace it - recurse
            left[key] = mergeKeys(leftVal.(m), rightVal.(m))
        } else {
            // key not in left so we can just shove it in
            left[key] = rightVal
        }
    }
    return left
}

참고 : 값 자체가 map[string]interface{}. 그래서 당신이있는 경우 left["x"] = 1right["x"] = 2시도 할 때 다음 위의 코드는 당황합니다 leftVal.(m).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.