(Deep) copier un tableau en utilisant jQuery [dupliquer]

possibilité de dupliquer:

Quelle est la manière la plus efficace de cloner un objet JavaScript?

j'ai besoin de copier un tableau (ordonné, non associatif) d'objets. Je suis à l'aide de jQuery. J'ai d'abord essayé

jquery.extend({}, myArray)

mais, naturellement, cela me donne en arrière un objet, où j'ai besoin d'un tableau (vraiment aimer jquery.étendre, par la voie).

alors, quelle est la meilleure façon de copier un tableau?

190
demandé sur Community 2009-02-19 17:01:20

8 réponses

Depuis Array.slice () ne fait pas de copie profonde, il n'est pas adapté aux tableaux multidimensionnels:

var a =[[1], [2], [3]];
var b = a.slice();

b.shift().shift();
// a is now [[], [2], [3]]

notez que bien que j'ai utilisé shift().shift() ci-dessus, le point est juste que b[0][0] contient un pointeur vers a[0][0] plutôt qu'une valeur.

de même delete(b[0][0]) entraîne également la suppression de a[0][0] et b[0][0]=99 modifie également la valeur de a[0][0] à 99.

jQuery extend méthode ne effectuer une copie en profondeur lorsque la valeur true est passé comme argument initial:

var a =[[1], [2], [3]];
var b = $.extend(true, [], a);

b.shift().shift();
// a is still [[1], [2], [3]]
268
répondu Noah Sussman 2012-08-21 15:10:43

$.extend(true, [], [['a', ['c']], 'b'])

Qui devrait le faire pour vous.

28
répondu geowa4 2017-03-29 13:00:37

je sais que vous recherchez une copie" profonde " d'un tableau, mais si vous n'avez qu'un seul tableau de niveau, vous pouvez utiliser ceci:

copier un tableau js natif est facile. Utilisez le tableau .slice() méthode qui crée une copie de la partie de la matrice.

var foo = ['a','b','c','d','e'];
var bar = foo.slice();

maintenant foo et bar sont 5 tableaux membres de 'a','b','c','d',' e '

bien sûr, c'est une barre de copie, pas une référence... donc, si tu as fait ça après...

bar.push('f');
alert('foo:' + foo.join(', '));
alert('bar:' + bar.join(', '));

vous dès maintenant:

foo:a, b, c, d, e
bar:a, b, c, d, e, f
17
répondu scunliffe 2015-07-12 16:48:59

tout dans JavaScript est passé par référence, donc si vous voulez une vraie copie profonde des objets dans le tableau, la meilleure méthode que je peux penser est de sérialiser l'ensemble du tableau à JSON et puis le désérialiser en arrière.

13
répondu 2009-02-19 18:28:50

si vous voulez utiliser pur JavaScript alors essayez ceci:

 var arr=["apple","ball","cat","dog"];
 var narr=[];

 for(var i=0;i<arr.length;i++){
     narr.push(arr[i]);
 }
 alert(narr); //output: apple,ball,vat,dog
 narr.push("elephant");
 alert(arr); // output: apple,ball,vat,dog
 alert(narr); // apple,ball,vat,dog,elephant
7
répondu frends 2011-11-17 15:53:00

j'ai trouvé cette fonction" deep object copy " que j'ai trouvé pratique pour dupliquer des objets en valeur. Il n'utilise pas jQuery, mais il est certainement profond.

http://www.overset.com/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value /

2
répondu Diodeus - James MacFarlane 2009-02-19 14:52:24

j'ai prévu de publier ce code dans la prochaine version de jPaq , mais d'ici là, vous pouvez l'utiliser si votre but est de faire une copie profonde des tableaux:

Array.prototype.clone = function(doDeepCopy) {
    if(doDeepCopy) {
        var encountered = [{
            a : this,
            b : []
        }];

        var item,
            levels = [{a:this, b:encountered[0].b, i:0}],
            level = 0,
            i = 0,
            len = this.length;

        while(i < len) {
            item = levels[level].a[i];
            if(Object.prototype.toString.call(item) === "[object Array]") {
                for(var j = encountered.length - 1; j >= 0; j--) {
                    if(encountered[j].a === item) {
                        levels[level].b.push(encountered[j].b);
                        break;
                    }
                }
                if(j < 0) {
                    encountered.push(j = {
                        a : item,
                        b : []
                    });
                    levels[level].b.push(j.b);
                    levels[level].i = i + 1;
                    levels[++level] = {a:item, b:j.b, i:0};
                    i = -1;
                    len = item.length;
                }
            }
            else {
                levels[level].b.push(item);
            }

            if(++i == len && level > 0) {
                levels.pop();
                i = levels[--level].i;
                len = levels[level].a.length;
            }
        }

        return encountered[0].b;
    }
    else {
        return this.slice(0);
    }
};

ce qui suit est un exemple de la façon d'appeler cette fonction pour faire une copie profonde d'un tableau récursif:

// Create a recursive array to prove that the cloning function can handle it.
var arrOriginal = [1,2,3];
arrOriginal.push(arrOriginal);

// Make a shallow copy of the recursive array.
var arrShallowCopy = arrOriginal.clone();

// Prove that the shallow copy isn't the same as a deep copy by showing that
// arrShallowCopy contains arrOriginal.
alert("It is " + (arrShallowCopy[3] === arrOriginal)
    + " that arrShallowCopy contains arrOriginal.");

// Make a deep copy of the recursive array.
var arrDeepCopy = arrOriginal.clone(true);

// Prove that the deep copy really works by showing that the original array is
// not the fourth item in arrDeepCopy but that this new array is.
alert("It is "
    + (arrDeepCopy[3] !== arrOriginal && arrDeepCopy === arrDeepCopy[3])
    + " that arrDeepCopy contains itself and not arrOriginal.");

vous pouvez jouer avec ce code ici à js Bin .

2
répondu Chris West 2011-03-13 02:21:19

et les types complexes? lorsque le tableau contient des objets... ou toute autre

ma variante:

Object.prototype.copy = function(){
    var v_newObj = {};
    for(v_i in this)
        v_newObj[v_i] = (typeof this[v_i]).contains(/^(array|object)$/) ? this[v_i].copy() : this[v_i];
    return v_newObj;
}

Array.prototype.copy = function(){
    var v_newArr = [];
    this.each(function(v_i){
        v_newArr.push((typeof v_i).contains(/^(array|object)$/) ? v_i.copy() : v_i);
    });
    return v_newArr;
}

Ce n'est pas la version finale, juste une idée.

PS: méthode chacun et contient sont des prototypes aussi.

2
répondu Xrumet 2012-03-13 11:36:42