2010-09-03 26 views
48

¿Cómo puedo combinar dos mapas STL en uno? Ambos tienen los mismos tipos de valor clave (mapa). Si hay superposición de las teclas, me gustaría dar preferencia a uno de los mapas.Combinar dos mapas STL

Respuesta

91

Suponiendo que se desea conservar los elementos de mapa, y combinar elementos en mapB para el que no hay ninguna clave de mapa:

mapA.insert(mapB.begin(), mapB.end()) 

va a hacer lo que quiere, creo.

EDIT: ejemplo añadiendo trabajar

#include <iostream> 
#include <map> 

void printIt(std::map<int,int> m) { 
    for(std::map<int,int>::iterator it=m.begin();it!=m.end();++it) 
     std::cout << it->first<<":"<<it->second<<" "; 
    std::cout << "\n"; 
} 

int main() { 
    std::map<int,int> foo,bar; 
    foo[1] = 11; foo[2] = 12; foo[3] = 13; 
    bar[2] = 20; bar[3] = 30; bar[4] = 40; 
    printIt(foo); 
    printIt(bar); 
    foo.insert(bar.begin(),bar.end()); 
    printIt(foo); 
    return 0; 
} 

de salida:

:!./insert 
1:11 2:12 3:13 
2:20 3:30 4:40 
1:11 2:12 3:13 4:40 
+0

No puedo ver cómo eso no anula un duplicado en mapA si las claves coinciden. Si digo que mapB era mi mapa "preferido", podría usar esto, creo. De esa forma, si es un duplicado, entonces la clave en mapB sería la que finalmente termina en el nuevo mapa (que ahora es mapA). ¿Suena correcto o estoy entendiendo mal qué inserto hace cuando hay un duplicado? – JonF

+9

La inserción no sobrescribirá los elementos existentes, cuando hay un choque en las teclas, el elemento ya existente tiene prioridad. –

+0

oh ya veo. desafortunadamente, no se construye. Genera un enorme mensaje de error – JonF

22

Si desea copiar las entradas de un mapa a otro, puede utilizar std::map 's insert:

targetMap.insert(sourceMap.begin(), sourceMap.end()); 

Pero tenga en cuenta que insert no actualiza elementos si su k ey ya está en targetMap; esos artículos se dejarán como están. Para sobrescribir los elementos, tendrá que copiar de manera explícita, por ejemplo:

for(auto& it : sourceMap) 
{ 
    targetMap[it.first] = it.second; 
} 

Si no le importa perder los datos en sourceMap, otra manera de lograr una copia-y-sobreescritura es insert el objetivo en la fuente y std::swap los resultados:

sourceMap.insert(targetMap.begin(), targetMap.end()); 
std::swap(sourceMap, targetMap); 

Después de cambiar, sourceMap contendrán targetMap 's datos antiguos y targetMap serán una combinación de los dos mapas, con preferencia por sourceMap' s entradas.

1

acuerdo con ISO/IEC 14882: 2003, sección 23.1.2, Tabla 69, a.insert expresión (i, j):

pre: i, j no son iteradores en a. inserta cada elemento del rango [i, j) si y solo si no hay un elemento con clave equivalente a la clave de ese elemento en contenedores con claves únicas;

Dado que std :: map debe seguir esta restricción, si desea dar preferencia a los "valores" de un mapa sobre otro, debe insertarlo. Por ejemplo,

std::map<int, int> goodKeys; 
std::map<int, int> betterKeys; 

betterKeys.insert(goodKeys.begin(), goodKeys.end()); 

lo tanto, si hay alguna clave equivalentes en goodKeys y betterKeys, se conservarán los "valores" de los betterKeys.