[Perl]-Tableau assoc à 2 dimensions

blux Messages postés 5032 Date d'inscription   Statut Modérateur Dernière intervention   -  
lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -
Bonjour,

j'ai une liste de données que j'aimerais agréger pour faire un tableau croisé, mais je ne sais pas coment on gère les tableaux asociatifs à deux dimensions en perl.

Un exemple, en entrée (dans un tableau) :

baie taille machine (entêtes de colonnes pour info)
A 50 machine1
A 20 machine1
B 5 machine1
A 5 machine2
C 10 machine2

en sortie je voudrais la somme de la deuxième colonne par machine et par baie :

machine A B C (entêtes de colonnes pour info)
machine1 70 5 0
machine2 5 0 10

J'ai imaginé créer un tableau à double entrée, mais je souhaiterais faire les additions de manière rapide sans avoir à parcourir le tableau à chaque fois. J'ai donc été voir du côté des tableaux associatifs qui semblent être la réponse à mon besoin, mais j'ai un peu de mal à comprendre comment faire tourner tout ça, et bien sûr je suis susceptible de rajouter des colonnes d'un traitement à l'autre...

Merci d'avance pour l'aide.

--
A+ Blux
 "Les cons, ça ose tout.
C'est même à ça qu'on les reconnait"

4 réponses

  1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    et bien sûr je suis susceptible de rajouter des colonnes d'un traitement à l'autre...

    tu peux établir le nombre de colonnes (voir le tableau @col)
    lami20j@debian:~/trash$ cat ccm.pl
    #!/usr/bin/perl
    use strict;use warnings;
    
    my %h;
    my $l;
    my @col = 'A' .. 'F';
    while(<DATA>){
      next if /^$/;
      /(\w+)\s*(\w+)\s*(\w+)/;
      push @{$h{$3}{$1}},$2;
    
      for $l(@col){
        push @{$h{$3}{$l}},0 unless exists $h{$3}{$l};
      }
    }
    
    print "machine @col\n";
    for my $k(keys %h){
      print "$k";
      for my $kk(sort keys %{$h{$k}}){
        print " ",eval ( join "+",@{$h{$k}{$kk}});
      }
      print "\n";
    }
    __END__
    A 50 machine1
    A 20 machine1
    B 5 machine1
    A 5 machine2
    C 10 machine2
    A 50 machine1
    A 20 machine1
    B 5 machine1
    A 5 machine2
    C 10 machine2
    D 50 machine1
    D 20 machine1
    E 5 machine1
    F 5 machine2
    C 10 machine2
    A 50 machine1
    A 20 machine1
    B 5 machine1
    A 5 machine2
    C 10 machine2
    
    lami20j@debian:~/trash$ perl ccm.pl
    machine A B C D E F
    machine1 210 15 0 70 5 0
    machine2 15 0 40 0 0 5
    
    1
  2. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    je vais voir ça ce soir ;-)
    0
  3. blux Messages postés 5032 Date d'inscription   Statut Modérateur Dernière intervention   3 455
     
    Cool !

    merci d'avance, je patiente...
    0
  4. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,
    voilà,
    #!/usr/bin/perl
    use strict;use warnings;
    
    my %h;
    
    while(<DATA>){
      /(\w+)\s*(\w+)\s*(\w+)/;
      push @{$h{$3}{$1}},$2;
      push @{$h{$3}{'A'}},0 unless exists $h{$3}{'A'};
      push @{$h{$3}{'B'}},0 unless exists $h{$3}{'B'};
      push @{$h{$3}{'C'}},0 unless exists $h{$3}{'C'};
    }
    
    print "machine A B C\n";
    for my $k(keys %h){
      print "$k";
      for my $kk(sort keys %{$h{$k}}){
        print " ",eval ( join "+",@{$h{$k}{$kk}});
      }
      print "\n";
    }
    __END__
    A 50 machine1
    A 20 machine1
    B 5 machine1
    A 5 machine2
    C 10 machine2
    

    Resultat
    root@debian:~/src# perl blux.pl
    machine A B C
    machine1 70 5 0
    machine2 5 0 10
    
    --
    lami20j
    0