2011-11-21 4 views
30

¿Cómo puedo clonar/copiar un mapa en Javascript?Clonar/copiar una variable de mapa de Javascript

Sé cómo clonar una matriz, pero ¿cómo puedo clonar/copiar un mapa?

var myArray = new Array(1, 2, 3); 
var copy = myArray.slice(); 
// now I can change myArray[0] = 5; & it wont affect copy array 

// Can I just do the same for map? 
var myMap = new ?? // in javascript is it called a map? 
var myMap = {"1": 1, "2", 2}; 
var copy = myMap.slice(); 
+0

en JavaScript, un mapa se llama un objeto . – slebetman

+0

¡hay tantos duplicados de esta pregunta que ni siquiera sé por dónde empezar! – Stefano

+7

En javascript 2015, hay un objeto de mapa real. –

Respuesta

10

Una forma sencilla es copiar cada propiedad del mapa de origen para el mapa de destino:.

var newMap = {}; 
for (var i in myMap) 
newMap[i] = myMap[i]; 
+2

esto es solo una copia superficial ... ¿y si myMap [i] es un mapa en sí? – Stefano

+0

Stefano, puede hacerlo si lo desea (verifique si es un objeto con typeof, luego realice una copia de sus propiedades ...posiblemente recurriendo a la misma función), pero tenga en cuenta que ahora debe preocuparse por la posibilidad de que sean un elemento ancestro en su que lo pondría en un ciclo infinito. Si realmente quiere una copia profunda, es posible que desee buscar en las bibliotecas para hacer eso. – rob

+1

Lo sé, pero creo que deberías haber escrito esto en tu respuesta en primer lugar ;-) – Stefano

2

No hay copia/clon incorporado. Puede escribir su propio método en copia escasa o profunda:

function shallowCopy(obj) { 
    var result = {}; 
    for (var i in obj) { 
     result[i] = obj[i]; 
    } 
    return result; 
} 

function deepCopy(obj) { 
    var result = {}; 
    for (var i in obj) { 
     // recursion here, though you'll need some non-trivial logic 
     // to avoid getting into an endless loop. 
    } 
    return result; 
} 

Todos los objetos en Javascript son dinámicos y se les pueden asignar nuevas propiedades. Un "mapa" como te refieres es en realidad solo un objeto vacío. Una matriz es también un objeto, con métodos como slice y propiedades como length.

+0

¡No entendí cuál es la diferencia entre las 2 funciones que escribiste! –

+0

@HasanAYousef La diferencia no está implementada; En una copia profunda, debe recurse (llame a deepCopy para cada hijo), pero como los niños pueden contener una referencia al elemento primario (por ejemplo, window.window2 = window), no puede copiar profundamente esas referencias sin entrar en un bucle infinito. – Nicole

2

no hay nada construido en

O bien utilizar una copiadora propiedad recursiva bien probado o si ISN rendimiento No es un problema, serializar a JSON y analizar de nuevo un nuevo objeto.

6

JQuery tiene un método para extender un objeto (uniendo dos objetos), pero este método también se puede usar para clonar un objeto al proporcionar un objeto vacío.

// Shallow copy 
var newObject = jQuery.extend({}, oldObject); 

// Deep copy 
var newObject = jQuery.extend(true, {}, oldObject); 

Más información se puede encontrar en el jQuery documentation.

111

Con la introducción de Mapas en JavaScript Es muy sencillo teniendo en cuenta el constructor acepta una iterable:

var newMap = new Map(existingMap) 

Documentación aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

+9

Esta es la respuesta correcta de hoy. –

+0

Una pequeña advertencia a lo anterior: la clonación de un mapa como este, invocará 'Map.prototype.entries' y' Map.prototype.set'. Eso significa que si escribe una clase que extienda Map _and_ sobrescribe cualquiera de estos dos métodos, simplemente escribir 'new ExtendedMap (extendedMapObj)' no funcionará si los métodos extendidos se basan en propiedades que no están disponibles para el super. –

+2

Otra nota es que parece que si los valores del mapa son tipos de referencia (como matrices), estos no se copian recursivamente, sino que se copian superficialmente. – ossek

1

me di cuenta de que el MAP debe requerir un tratamiento especial, por lo tanto, con todas las sugerencias en este hilo, el código será:

function deepClone(obj) { 
    if(!obj || true == obj) //this also handles boolean as true and false 
     return obj; 
    var objType = typeof(obj); 
    if("number" == objType || "string" == objType) // add your immutables here 
     return obj; 
    var result = Array.isArray(obj) ? [] : !obj.constructor ? {} : new obj.constructor(); 
    if(obj instanceof Map) 
     for(var key of obj.keys()) 
      result.set(key, deepClone(obj.get(key))); 
    for(var key in obj) 
     if(obj.hasOwnProperty(key)) 
      result[key] = deepClone(obj[ key ]); 
    return result; 
} 
0

Muy simple para clonar un mapa ya que lo que estás hablando es jus t un objeto. Hay una Map en ES6 que usted debe mirar hacia arriba, pero para copiar un objeto, sólo tiene que utilizar Object.assign()

let map = {"a": 1, "b": 2} 
let copy = Object.assign({}, map); 

También puede utilizar cloneDeep() de Lodash

let copy = cloneDeep(map); 
Cuestiones relacionadas