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

JavaScript Discussion :

deep copy avec Array.from


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut deep copy avec Array.from
    Bonjour,

    Une des utilisations possibles de Array.from, si j'ai bien compris, est de faire une copie d'un tableau en préservant l'original ( = deep copy).
    J'ai fait un premier test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    const a1 = [2, 3, 5];
    const a2 = Array.from(a1);
    a2[0] += 1;
    console.log(a1, a2);
    // renvoie (3) [2, 3, 5] (3) [3, 3, 5]
    Mon tableau d'origine est bien intact.
    Par ailleurs, je suis en train de rédiger une classe me permettant de travailler avec des matrices. Le constructeur prend en argument un tableau de tableaux:
    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
     
    class Matrix {
      constructor(array) {
        this.array = array;
        this.height = array.length;
        this.width = array[0].length;
      }
      multiply(k) {
        const temp = Array.from(this.array);
        for (let i = 0; i < this.height; i += 1) {
          for (let j = 0; j < this.width; j += 1) {
            temp[i][j] *= k;
          }
        }    
        return new Matrix(temp);
      }
    }
     
    const M = new Matrix([[1, 2], [1, 0]]);
    const N = M.multiply(2);
    console.log(M);
    Et là, cela ne fonctionne pas.
    Ma matrice M initiale est multipliée par 2 alors que je voulais que seule ma matrice N soit modifiée.
    j'ai fait quelques tests: si je me contente d'ajouter 1 à un des nombres de la matrice temp, la matrice désignée par this.array est aussi modifiée.
    Quelqu'un peut-il m'éclairer?
    Merci d'avance.

    Raphaël

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 235
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 235
    Points : 15 532
    Points
    15 532
    Par défaut
    Array.from ne fait une copie que de la 1re dimension. pour faire une copie de la 2e dimension, vous devrez faire une boucle qui parcourt toute la matrice.

  3. #3
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut merci beaucoup
    Merci à vous.

  4. #4
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut code corrigé grâce à Mathieu
    Au cas où cela intéresse quelqu'un, je colle la solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     multiply(k) {
        // deep copy de this.array
        const temp = [];
        for (let i = 0; i < this.height; i += 1) {
          temp.push(Array.from(this.array[i]));
        }
        for (let i = 0; i < this.height; i += 1) {
          for (let j = 0; j < this.width; j += 1) {
            temp[i][j] *= k;
          }
        }
        return new Matrix(temp);
      }

  5. #5
    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
    Bonjour,
    indépendamment tu soucis bien réel sur la copie des Array, ce qui m'interpelle c'est la logique de ta Class.

    La méthode multiply devrait agir sur l'instance en cours et non pas sur une nouvelle !
    Si tu souhaites utiliser les données déjà initialisé alors il te faut créer une méthode clone pour au final écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const M = new Matrix([[1, 2], [1, 0]]);
    const N = M.clone().multiply(3);
    console.log(M);
    console.log(N);
    ce qui reste somme toute bien plus compréhensible.

    J'aurais donc plus vu quelque chose comme :
    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
    class Matrix {
      constructor(array) {
        this.array = array;
        this.height = array.length;
        this.width = array[0].length;
      }
      multiply(k) {
        for (let i = 0; i < this.height; i += 1) {
          for (let j = 0; j < this.width; j += 1) {
            this.array[i][j] *= k;
          }
        }
        return this;
      }
      clone() {
        return new Matrix(deepCopyArray(this.array));
      }
    }
    en utilisant une fonction générique deepCopyArray comme :
    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
    /**
     * Function récursive pour copier un Array en profondeur
     * @param   {Array} arrayIn  - Array devant être copier
     * @returns {Array} arrayOut - copie de l'Array d'entrée
     */
    const deepCopyArray = (arrayIn) => {
      const arrayOut = [];
      if (!Array.isArray(arrayIn)) {
        return arrayIn;
      }
      arrayIn.forEach((val, ind) => {
        arrayOut[ind] = deepCopyArray(val);
      });
      return arrayOut;
    }

  6. #6
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut réponse à NoSmoking
    Merci pour ta réponse et pour ton analyse.

    J'avais effectivement prévu de faire comme tu l'indiques au départ mais il me semble que j'avais es-lint qui me reprochait quelque chose, je ne sais plus quoi.
    Peut-être avais-je mal géré l'affaire et oublié le "return this" en fin de méthode.
    Pour ce que je veux faire, ma méthode marche tout de même mais c'est vrai que je génère une nouvelle instance de manière inutile.

    Merci pour ta fonction récursive de copie de tableau: élégant.

    Raphaël

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme avec SELECT..FROM..WHERE
    Par VBBBA dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 08/09/2006, 15h58
  2. [VB-Excel]problème de syntaxe avec Array
    Par DomBourti dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 13/07/2006, 21h30
  3. Probleme de type avec Array
    Par BECHE dans le forum Langage
    Réponses: 5
    Dernier message: 30/03/2006, 23h05
  4. Petit probleme avec Arrays.Sort(...)
    Par Seth77 dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 15/01/2006, 12h48
  5. création de tableaux avec Array() et élément 'fantome'
    Par Talieth dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 22/11/2005, 09h49

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