IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contributions JavaScript / AJAX Discussion :

Javascript : Comment faire une copie d'un tableau ? (Array javascript)


Sujet :

Contributions JavaScript / AJAX

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut Javascript : Comment faire une copie d'un tableau ? (Array javascript)
    http://javascript.developpez.com/faq...#copieTableaux

    Bon je viens de voir que la FAQ au niveau des tableaux fait un peu peur, dans le sens où certains codes proposés sont vieux et d'autres ne sont pas dans les bonnes pratiques.

    Je commence le nettoyage par le partie pour Copier un tableau.
    Je propose que toutes les solutions proposés soient abandonnées, car elles consomment, sont vieilles, et surtout qu'une méthode existe et est compatible avec IE6 :
    L'utilisation de slice();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var a = [1,2,3]
    var b= a.slice();
     
    console.log(a == b) => false;
    La simple utilisation de slice est suffisante pour copier un tableau.

    D'ailleurs on peut utiliser slice pour transformer une nodelist en tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var divs = document.getElementsByTagName('div');
    var divsInArray = Array.prototype.slice.call(this, divs);
     
    divs instanceof Array => false;
    divsInArray instanceof Array => true;
    S'il faut que je réécrive la question de la faq je ferai, mais avant j'attends vos avis là dessus

  2. #2
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    J'allais justement ouvrir le même topic pour cette même raison

    Il y a plein d'autres petites choses à changer sur la FAQ tableaux, notamment toutes les méthodes ECMAScript 5 à documenter. Ca vaut peut-être le coup que j'ouvre un nouveau topic pour tout détailler.
    One Web to rule them all

  3. #3
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    Utiliser la méthode concat() est quasi similaire en terme de performance.

    Mais ces méthodes sont limitées. En effet, elles ne font pas une copie profonde du tableau. Un exemple vaudra mieux que mes explications :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var a =[[1], [2], [3]];
    var b = a.slice();
    console.log(a); // [[1], [2], [3]]
    console.log(b); // [[1], [2], [3]]
    console.log(a === b); // false
     
    // Jusque là, tout est normal. Mais si on change, par exemple, la valeur du premier élément du premier tableau de b. Le premier élément du premier tableau de a est également modifié
    b[0][0] = 99;
    console.log(a); // [[99], [2], [3]]
    console.log(b); // [[99], [2], [3]]
    Tu l'auras compris, b[0][0] contient un pointeur vers a[0][0] plutôt que la valeur car slice fait juste une copie de surface. Si le tableau contient d'autre tableau/objet, il passera alors leur référence mais ne les copiera pas.

    Personnellement, jutilise ce bout de code, pris au détour du net, pour cloner "profondément" un Object ou un Array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function deepCopy(obj) {
      if (Object.prototype.toString.call(obj) === '[object Array]') {
        var len = obj.length, out = new Array(len), i = 0;
        for ( ; i < len; i++ ) {
          out[i] = arguments.callee(obj[i]);
        }
        return out;
      }
      if (typeof obj === 'object') {
        var out = {}, i;
        for ( i in obj ) {
          out[i] = arguments.callee(obj[i]);
        }
        return out;
      }
      return obj;
    }
    var a = [[1], [2], [3]];
    var b = deepCopy(a);
    console.log(a); // [[1], [2], [3]]
    console.log(b); // [[1], [2], [3]]
    console.log(a === b); // false
    b[0][0] = 99;
    console.log(a); // [[1], [2], [3]]
    console.log(b); // [[99], [2], [3]]
    Ou en jQuery :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var b = $.extend(true, [], a);
    D'ailleurs on peut utiliser slice pour transformer une nodelist en tableau
    C'est tout a fait vrai, mais pour être plus large, cela permet de transformer des "array-like" en tableau. En gros, les "array-like" sont les objets retournés par toutes les méthodes du DOM retournant une "liste" de quelque chose et la variable spéciale arguments.

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut

    Citation Envoyé par SylvainPV Voir le message
    J'allais justement ouvrir le même topic pour cette même raison
    Il y a plein d'autres petites choses à changer sur la FAQ tableaux, notamment toutes les méthodes ECMAScript 5 à documenter. Ca vaut peut-être le coup que j'ouvre un nouveau topic pour tout détailler.
    n'hésite pas à ouvrir un nouveau topic avec tes propositions, elles pourront de la sorte être discutées, démontées(non j'déco**e).

    Tu peux lire l'introduction qu'à écrite vermine, si ce n'est déjà fait, c'est ici

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    On veut une copie du tableau, pas une copie profonde (dans notre cas à nous)
    Et pour tester un tableau ton test est compliqué
    pourquoi ne pas faire un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(obj instanceof Array)
    ?

  6. #6
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    Oui, c'est une bonne méthode, mais il faudra l'indiquer je pense

    Et pour tester un tableau ton test est compliqué
    instanceof est bugué.

    C'est l'alternative proposé à Array.isArray() d'ES5. Voir MDN
    C'est pour palier à un problème de multiframe dans le DOM. Les tableaux créés dans une frame ne partagent pas le même [[Prototype]] avec les tableaux créés dans une autre frame.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var arr = [];
    arr instanceof Array; // true
    Ce code fonctionne car Array.prototype référence le même objet [[Prototype]] de arr.
    Or, dans un environnement DOM multiframe, les [[Prototype]] différent du coup instanceof ne fonctionne plus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var iframe = document.createElement('iframe');
    document.body.appendChild(iframe);
    ArrayFromFrame = window.frames[0].Array;
    var arr = new ArrayFromFrame('toto', 'tata'); // ['toto', 'tata']  
     
    // fail
    arr instanceof Array; // false
     
    // OK
    Object.prototype.toString.call(arr) === '[object Array]'; // true

  7. #7
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    C'est bizarre je ne peux pas éditer le premier post du topic, dommage.

    Bon je voulais indiquer qu'il y a une erreur dans mon code :
    Pour copier un tableau au lieu de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Array.prototype.slice.call(this, divs);
    il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Array.prototype.slice.call(divs);
    Et cette fonction marche très bien pour transformer les Arraylike en array.

  8. #8
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par arnogues Voir le message
    C'est bizarre je ne peux pas éditer le premier post du topic, dommage.
    normal, au bout de 3 jours il n'est plus possible d'éditer un message

  9. #9
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Up ?

    Le topic date de quatre mois et la remarque sur l'utilisation est toujours aussi pertinente. Elle remplace les 3 solutions évoquées : http://javascript.developpez.com/faq...#copieTableaux
    One Web to rule them all

  10. #10
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 912
    Points
    79 912
    Par défaut
    Il faudrait que je trouve le temps de m'occuper de la relecture de la FAQ.

  11. #11
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par vermine Voir le message
    Il faudrait que je trouve le temps de m'occuper de la relecture de la FAQ.
    Quels points sont à revoir ?

  12. #12
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 912
    Points
    79 912
    Par défaut
    Je ne sais pas trop. En gros, il faudrait s'assurer que chaque Q/R ait été relue et que tout le monde soit d'accord sur les corrections à faire.

    Ensuite, trouver le temps de mettre en ligne les corrections. Par paquets définis, afin de faire plusieurs annonces dans le temps (appel à ressources régulier).

  13. #13
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    On s'était réparti la tâche et certaines Q/R ont été mises à jour. Je pense que ce qu'il reste à faire ce sont les messages tagués [A relire].

  14. #14
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 912
    Points
    79 912
    Par défaut
    Ben oui. Ca fait beaucoup. Il faudrait que quelqu'un certifie que tous les [A relire] sur les formulaires sont ok. Et tant pis si c'est toi qui te certifie toi-même. Mais comme ça je pourrais mettre ça sur l'environnement de travail, passer en relecture orthographique et puis publier/annoncer.

    Tu penses pouvoir t'en charger ?

  15. #15
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Je préférais que Bovino ou SpaceFrog (ou quelqu'un d'autre) me donne son avis car j'ai pu laisser passer une erreur. De plus, certains scripts nécessitent une vérification sous Chrome que je n'ai pas sur ma machine.

  16. #16
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut

    je regardes si je peux faire quelque chose pour vous ce week-end, risque de dépendre de mes soucis actuels de réseaux.

  17. #17
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    super

Discussions similaires

  1. comment faire une bordure a un tableau fait en vbs
    Par dvechamb dans le forum ASP.NET
    Réponses: 6
    Dernier message: 07/03/2012, 17h20
  2. comment faire une copie d'un serveur sur un autre
    Par bomonde dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 16/12/2010, 15h41
  3. Réponses: 4
    Dernier message: 05/09/2009, 13h25
  4. Réponses: 11
    Dernier message: 23/06/2007, 00h32
  5. Réponses: 9
    Dernier message: 03/09/2006, 23h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo