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 :

Implémenter une propriété à un tableau en travaillant sur this


Sujet :

JavaScript

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Points : 30
    Points
    30
    Par défaut Implémenter une propriété à un tableau en travaillant sur this
    Bonjour,

    Je cherche à implémenter une méthode transpose() à un any[][].

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Object.defineProperty(Array.prototype, 'transpose', {
        value : function () {
            return this[0].map((_, colIndex) => this.map(row => row[colIndex]));
     
            // this = new Array();
            // this.push(...);
        }
    });
    Cette fonction fonctionne bien, mais je souhaiterais pouvoir juste écrire arr.transpose() au lieu de arr = arr.transpose().

    Bien sûr, je peux utiliser le tableau retourné comme varianble intermédiaire et ensuite "repeupler" via this[i][j], mais ceci ne fonctionne que dans le cas où le tableau est carré.

    Ps : je ne souhaite pas utiliser de librairies externes.

    Merci par avance !

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 075
    Points : 44 667
    Points
    44 667
    Par défaut
    Bonjour,
    il te faut réaffecter les valeurs à this, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Object.defineProperty(Array.prototype, 'transpose', {
      value: function() {
        result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
        result.forEach((val, i) => {
          this[i] = val;
        })
        return this;
      },
    });

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Points : 30
    Points
    30
    Par défaut
    Merci, mais ça ne me semble pas corriger le problème, car ça conserve le lignes "extra" si il y a plus de lignes que de colonnes..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [ [1, 2], [3, 4], [5, 6] ].transpose() => [ [1, 3, 5], [2, 4, 6], [5, 6] ]

  4. #4
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 886
    Points : 3 725
    Points
    3 725
    Par défaut
    Oui c'est normal d’après le code de NoSmoking : dans cet exemple le tableau result contient deux tableaux alors que le tableau de départ en contient trois du coup dans la boucle on rafraichi les deux premiers tableaux mais le troisième reste intact.

    Il faudrait donc effacer le troisième tableau...

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 075
    Points : 44 667
    Points
    44 667
    Par défaut
    Il va de soit que si tu ne travailles pas sur des matrices carrées il te faut « vidanger » le tableau avant.
    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
    Object.defineProperty(Array.prototype, 'transpose', {
      value: function() {
        // traitement
        result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
        // vidange propre de l'array
        while(this.length){
          this.pop();
        }
        // affectatuion des nouvelles valeurs
        result.forEach((val, i) => {
          this[i] = val;
        })
        return this;
      },
    });

  6. #6
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 886
    Points : 3 725
    Points
    3 725
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Il va de soit que si tu ne travailles pas sur des matrices carrées il te faut « vidanger » le tableau avant.
    Ah justement je cherchais un bon moyen de faire cette "vidange", je n'avais pas pensée à une boucle avec pop.

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

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 356
    Points : 15 702
    Points
    15 702
    Par défaut
    en partant du code de NoSmoking, vous pouvez vider le tableau au milieu comme cela :
    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
    	Object.defineProperty(
    		  Array.prototype
    		, "transpose"
    		,
    		{
    			"value" : function() {
     
    				let result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
     
    				this.splice(0, this.length);
     
    				result.forEach((val, i) => {
    					this[i] = val;
    				})
     
    				return this;
     
    			},
    		}
    	);
    par contre je ne sais pas si çela utilise beaucoup de ressources donc ça reste à vérifier avant de l'utiliser sur des gros tableaux.

  8. #8
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 886
    Points : 3 725
    Points
    3 725
    Par défaut
    Citation Envoyé par mathieu Voir le message
    par contre je ne sais pas si çela utilise beaucoup de ressources donc ça reste à vérifier avant de l'utiliser sur des gros tableaux.
    J'avais aussi pensée à splice mais je pense que ce serait peut-être plus rapide si on le mettait après la boucle en adaptant les paramètres pour ne supprimer que les éléments en trop :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Object.defineProperty(Array.prototype, "transpose4", {
                "value": function () {
                    let result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
                    result.forEach((val, i) => {
                        this[i] = val;
                    })
                    this.splice(result.length, this.length);
                    return this;
                },
            });;

    Je pense qu'on peut faire pareil avec la boucle pop de NoSmoking :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Object.defineProperty(Array.prototype, 'transpose21', {
                value: function () {
                    // traitement
                    result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
                    // affectatuion des nouvelles valeurs
                    result.forEach((val, i) => {
                        this[i] = val;
                    })
     
                    while (this.length > result.length) {
                        this.pop();
                    }
                    return this;
                },
            });
    Mais là peut-être qu'une boucle for* serait mieux... :
    *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (let l = result.length; this.length != l;) {
       this.pop();
    }

  9. #9
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 886
    Points : 3 725
    Points
    3 725
    Par défaut
    Sinon pour vider un tableau arr, on avait vu qu'on pouvait faire : arr.length = 0, ça semble rapide mais il y a peut-être une contre partie (revers de la médaille)

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Points : 30
    Points
    30
    Par défaut
    Meri pour vos réponses, ça fonctionne très bien.

    Je m'aperçois que je restais "bloquer" sur le fait que je ne pouvais pas écrire this = ....
    Pour l'instant, je ne traite que de colonnes de d'une centaine de valeurs ; donc le temps importe peu, mais je préfère concevoir mes algorithmes sans tenir compte de ce type d'hypothèses.

    Par ailleurs, j'ai lu comme quoi, il n'était pas très bon de définir des propriétés en se basant sur un propotype. Du coup, je n'ai pas de l'autocomplétion sous VS Code. Savez-vous s'il est possible de quand même avoir l'auto-complétion (ça me rajoute plein de warnings) ?

    Ps : plus exactement, je code des scripts en pseudo-TypeScript via un utilitaire clasp pour Google Sheets et cie.

  11. #11
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 886
    Points : 3 725
    Points
    3 725
    Par défaut
    Citation Envoyé par Orbeaman Voir le message
    Je m'aperçois que je restais "bloquer" sur le fait que je ne pouvais pas écrire this = ....
    Ben oui on ne peut pas normalement sinon tu perds la référence au tableau...

    A ne pas confondre avec this[i] =......

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 075
    Points : 44 667
    Points
    44 667
    Par défaut
    Concernant le « vidage » du tableau, j'ai mis cela pour montrer une façon « propre » de faire mais il y a toujours moyen effectivement de jouer sur la longueur après affectation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Object.defineProperty(Array.prototype, 'transpose', {
      value: function() {
        result = this[0].map((_, colIndex) => this.map(row => row[colIndex]));
        result.forEach((val, i) => {
          this[i] = val;
        })
        this.length = result.length;
        return this;
      },
    });
    voilà tu n'as que l'embarras du choix !!!

    j'ai lu comme quoi, il n'était pas très bon de définir des propriétés en se basant sur un propotype.
    c'est surtout quand il s'agit d'objets globaux.

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

Discussions similaires

  1. [CustomControls Library] Comment implémenter une propriété ToolTip commune ?
    Par neguib dans le forum Windows Presentation Foundation
    Réponses: 9
    Dernier message: 31/10/2008, 08h23
  2. Réponses: 11
    Dernier message: 04/01/2007, 09h47
  3. Réponses: 7
    Dernier message: 06/04/2006, 18h17
  4. Comment rendre une ligne de tableau en liens
    Par Death83 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 10
    Dernier message: 11/09/2005, 23h14
  5. Réponses: 17
    Dernier message: 04/04/2005, 17h50

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