2011-11-21 14 views
30

Come faccio a clonare/copiare una mappa in Javascript?Clona/Copia una variabile di mappa Javascript

So come clonare un array ma come faccio a clonare/copiare una mappa?

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

in JavaScript, una mappa si chiama un oggetto . – slebetman

+0

ci sono così tanti duplicati di questa domanda che non so nemmeno da dove cominciare! – Stefano

+7

In javascript 2015, c'è un vero oggetto Mappa. –

risposta

10

Un modo semplice è quello di copiare ogni proprietà della mappa di origine per la mappa di destinazione:.

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

questa è solo una copia superficiale ... cosa succede se myMap [i] è una mappa stessa? – Stefano

+0

Stefano, puoi farlo se vuoi (controlla se è un oggetto con typeof, quindi esegui una copia delle sue proprietà ...possibilmente ricorrendo alla stessa funzione), ma tieni presente che ora devi preoccuparti della possibilità che il loro essere un elemento antenato nel loro quale ti metta in un ciclo infinito. Se vuoi davvero una copia approfondita, potresti voler consultare le librerie per farlo. – rob

+1

Lo so, ma penso che dovresti aver scritto questo nella tua risposta in primo luogo ;-) – Stefano

2

Non vi è alcun clone/copia incorporato. Puoi scrivere il tuo metodo su una copia superficiale o profonda:

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; 
} 

Tutti gli oggetti in Javascript sono dinamici e possono essere assegnati nuove proprietà. Una "mappa" a cui ci si riferisce è in realtà solo un oggetto vuoto. Una matrice è anche un oggetto, con metodi come slice e proprietà come length.

+0

Non ho capito qual è il diverso tra le 2 funzioni che hai scritto! –

+0

@HasanAYousef La differenza non è implementata; In una copia profonda, devi recurse (chiama deepCopy per ogni bambino), ma poiché i bambini possono contenere un riferimento al genitore (ad es. Window.window2 = window), non puoi copiare in profondità quei riferimenti senza entrare in un ciclo infinito. – Nicole

2

Non c'è nulla di costruito in

Utilizzare un copiatrice proprietà ricorsiva ben testato o se isn prestazioni è un problema, serializza su JSON e analizza di nuovo un nuovo oggetto.

6

JQuery ha un metodo per estendere un oggetto (unendo due oggetti), ma questo metodo può anche essere utilizzato per clonare un oggetto fornendo un oggetto vuoto.

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

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

Maggiori informazioni si possono trovare nel jQuery documentation.

111

Con l'introduzione di mappe in JavaScript è abbastanza semplice considerando il costruttore accetta un iterabile:

var newMap = new Map(existingMap) 

documentazione qui: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

+9

Questa è la risposta corretta di oggi. –

+0

Un piccolo avvertimento a quanto sopra: la clonazione di una mappa come questa, invocherà 'Map.prototype.entries' e' Map.prototype.set'. Ciò significa: se scrivi una classe che estende Map _and_ sovrascrive uno di questi due metodi, la semplice scrittura di 'new ExtendedMap (extendedMapObj)' non funzionerà se i metodi estesi si basano su proprietà che non sono disponibili per il super. –

+2

Un'altra nota è che sembra che se i valori della mappa sono tipi di riferimento (come gli array), questi non sono ricorsivamente copiati in profondità, ma copiati in modo superficiale. – ossek

1

ho notato che mappa dovrebbe richiedere un trattamento speciale, quindi con tutti i suggerimenti questo thread, il codice sarà:

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

Molto semplice per clonare una mappa poiché quello di cui stai parlando è jus t un oggetto. C'è un Map in ES6 che si dovrebbe guardare in alto, ma per copiare un oggetto, basta usare Object.assign()

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

È inoltre possibile utilizzare cloneDeep() da Lodash

let copy = cloneDeep(map); 
Problemi correlati