2016-09-08 2 views
2

Я использую Golang, и по какой-то причине мне нужно объединить результаты из разных запросов к базе данных, все из которых возвращают мне []map[string]interface{} I «Я думаю о добавлении, но его просто недостаточно ясно, если это возможно. Каков конечный тип данных, на который я смотрю?Объединить два или более [] map [string] interface {} типы в одном в Golang

Очевидно, что массив карт интерфейсов с ключами как строки должен иметь возможность просто «присоединить» (concat, если возможно) к другому массиву карт интерфейсов с ключами в виде строк!

Итак, каков механизм для достижения этого?

+1

хорошо, вы можете перебирать: 'для к, v: = диапазон (map1) {map2 [к] = v}', но вы должны решить, что происходит, когда есть ключ столкновения. вы можете проверить это с помощью 'v, ok: = map2 [k]; if! ok {...} ' – Plato

+0

Извините, я пропустил ломтик. Вы можете сделать «newslice: = append (slice1, slice2 ...)», см. Https://blog.golang.org/slices#TOC_10. – Plato

+1

Несомненно, вы можете добавить только результат: = append (result1, result2 ...), если результаты одного типа [] map [string] interface {} – Uvelichitel

ответ

4

Даже ответ уже приведен в комментариях выше. Я отправлю короткий пример, как это можно достичь.

package main 

import (
    "fmt" 
) 

func main() { 
    result := []map[string]interface{}{} 

    mp1 := map[string]interface{}{ 
     "one" : 1, 
     "two" : 2, 
    } 

    mp2 := map[string]interface{}{ 
     "three" : 3, 
     "four" : 4, 
    } 

    mp3 := make(map[string]interface{}) 
    for k, v := range mp1 { 
     if _, ok := mp1[k]; ok { 
      mp3[k] = v   
     } 
    } 

    for k, v := range mp2 { 
     if _, ok := mp2[k]; ok { 
      mp3[k] = v 
     } 
    } 

    result = append(result, mp1, mp2) 
    fmt.Println(result) 
} 

Выход будет:

[map[one:1 two:2] map[three:3 four:4]] 

Playground example

+0

Kudos! В моем случае у меня были map1, map2 и map3 все типы [] map [string] interface {}, и я сделал - результат: = map1 result = append (result, map2 ...) result = append (результат, result, map3 ...) И это именно то, что мне нужно! –

3

Другой ответ является правильным. Вы также можете написать вспомогательную функцию, чтобы избежать повторных слияний карт.

// overwriting duplicate keys, you should handle that if there is a need 
func mergeMaps(maps ...map[string]interface{}) map[string]interface{} { 
    result := make(map[string]interface{}) 
    for _, m := range maps { 
     for k, v := range m { 
      result[k] = v 
     } 
    } 
    return result 
} 

func main() { 
    log.Println(`started`) 

    v := []map[string]interface{}{ 
     map[string]interface{}{ 
      `one`: 1, 
      `two`: 2, 
     }, 
     map[string]interface{}{ 
      `one`: `I`, 
      `three`: 3, 
      `other`: `NAN`, 
     }, 
     map[string]interface{}{ 
      `name`: `Bob`, 
      `age`: 300, 
     }, 
    } 

    m := mergeMaps(v...) 
    log.Println(m, len(m)) 
} 
+1

Имеет смысл и полезен в долгосрочной перспективе! Спасибо! –

+0

Обратите внимание, что это совершенно другой тип работы! 'append' работает на срезах. Если вы объедините две карты, вы можете определить две разные операции слияния ('A: = A MERGE B'), где B [k] перезаписывает A [k], а другой, где A [k] сохраняет свои значения над B [k]. – ikrabbe

+0

Верно, поэтому этот ответ начинается с «Другой ответ правильный». Несмотря на то, что он обрабатывает json (или какой-то внешний поток данных), есть некоторая распространенная ошибка иметь «кусок карт», а 'mp3' фактически не используется нигде внутри первого ответа. –

Смежные вопросы