[PERL] Supprimer valeure d'un tableau contenant des hash

Supprimer valeure d'un tableau contenant des hash [PERL] - Perl - Programmation

Marsh Posté le 16-12-2011 à 12:09:19    

Bonjour, :hello:  
 
J'ai un tableau (@tabProc_temp) qui est construit comme ceci:

Code :
  1. $VAR1 = bless( {
  2.                  'PERE' => '4 5',
  3.                  'ID_PROCESS' => '7',
  4.                  'LOCK' => '0',
  5.                  'FILS' => '8',
  6.                  'TYPE' => 'PERE',
  7.                  'STARTED' => '0',
  8.                  'ALIAS' => 'alias7'
  9.                }, 'Job' );
  10. $VAR2 = bless( {
  11.                  'PERE' => '7 6 3',
  12.                  'ID_PROCESS' => '8',
  13.                  'LOCK' => '0',
  14.                  'FILS' => 'NULL',
  15.                  'TYPE' => 'FILS',
  16.                  'STARTED' => '0',
  17.                  'ALIAS' => 'alias8'
  18.                }, 'Job' );
  19. $VAR3 = bless( {
  20.                  'PERE' => '3',
  21.                  'ID_PROCESS' => '9',
  22.                  'LOCK' => '0',
  23.                  'FILS' => 'NULL',
  24.                  'TYPE' => 'FILS',
  25.                  'STARTED' => '0',
  26.                  'ALIAS' => 'alias9'
  27.                }, 'Job' );


 
Mon probleme est que je ne trouve pas comment supprimer un des élément de ce tableau en fonction de la valeure de "'ID_PROCESS' => 'x',".
Par exemple, je voudrai supprimer seulement l’élément qui a pour "ID_PROCESS":8.
 
Le résultat serait donc:

Code :
  1. $VAR1 = bless( {
  2.                      'PERE' => '4 5',
  3.                      'ID_PROCESS' => '7',
  4.                      'LOCK' => '0',
  5.                      'FILS' => '8',
  6.                      'TYPE' => 'PERE',
  7.                      'STARTED' => '0',
  8.                      'ALIAS' => 'alias7'
  9.                    }, 'Job' );
  10.     $VAR3 = bless( {
  11.                      'PERE' => '3',
  12.                      'ID_PROCESS' => '9',
  13.                      'LOCK' => '0',
  14.                      'FILS' => 'NULL',
  15.                      'TYPE' => 'FILS',
  16.                      'STARTED' => '0',
  17.                      'ALIAS' => 'alias9'
  18.                    }, 'Job' );


 
Avez vous une idée pour faire cela?  :whistle:  
 
Merci,
Cordialement,
Benjamin.


Message édité par Super_carotte le 16-12-2011 à 12:11:14
Reply

Marsh Posté le 16-12-2011 à 12:09:19   

Reply

Marsh Posté le 16-12-2011 à 12:17:19    

Bonjour,
 
La manière standard:  
Parcourir l'array et tester chaque élément pour avoir l'indice de l'élément à retirer
Quand il est trouvé, appeller splice avec cet indice: splice(@array, $indextoremove,1);

ne convient pas?
 
A+,


Message édité par gilou le 16-12-2011 à 12:17:51

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-12-2011 à 15:30:00    

Je vois bien comment parcourir le tableau:

Code :
  1. my $ID_inFork = "8";
  2. foreach my $row_inFork (@tabProc_temp)  #pour chaque processus
  3. {
  4. if ($row_inFork->{ID_PROCESS} == $ID_inFork )
  5. {
  6. my $indextoremove = ?????;
  7. splice(@tabProc_temp, $indextoremove,1);
  8. }
  9. }


 
Mais je ne sais pas quoi mettre a la place de $indextoremove.  
J'ai essayé avec:

Code :
  1. my $indextoremove = $row_inFork;

mais ça ne fonctionne pas.
Je ne vois pas comment récupérer cette valeur vu que mon tableau ressemble a:

Code :
  1. $VAR1 = bless( {
  2.                  'PERE' => '4 5',
  3.                  'ID_PROCESS' => '7',
  4.                  'LOCK' => '0',
  5.                  'FILS' => '8',
  6.                  'TYPE' => 'PERE',
  7.                  'STARTED' => '0',
  8.                  'ALIAS' => 'alias7'
  9.                }, 'Job' );
  10. $VAR2 = bless( {
  11.                  'PERE' => '7 6 3',
  12.                  'ID_PROCESS' => '8',
  13.                  'LOCK' => '0',
  14.                  'FILS' => 'NULL',
  15.                  'TYPE' => 'FILS',
  16.                  'STARTED' => '0',
  17.                  'ALIAS' => 'alias8'
  18.                }, 'Job' );


Message édité par Super_carotte le 16-12-2011 à 15:55:15
Reply

Marsh Posté le 16-12-2011 à 20:47:18    

A priori, quelque chose comme ceci:
my $ID_inFork = "8";
my @indextoremove = ();
foreach my $row_inFork (0..$#tabProc_temp) {
  push(@indextoremove, $row_inFork) if ($tabProc_temp[$row_inFork]->{ID_PROCESS} == $ID_inFork )
}
foreach ((reverse @indextoremove)) {
  splice(@tabProc_temp, $_, 1);
}
 
Un tableau pour collecter les indices a supprimer
Un parcours du tableau par indice croissant avec collecte des indices à supprimer
Une inversion du tableau pour retirer par ordre décroissant, sinon, les indices collectés ne vont plus être bons pour splice dès qu'il a été appliqué une fois.
Le retrait des éléments du tableau.
 
Au cas ou l'on sait qu'il n'y a au plus qu'une seule valeur d'indice à retirer, ça peut se simplifier.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-12-2011 à 11:09:27    

Merci Gilou!  :D  
 
Ton code fonctionne parfaitement. Comme je l'esperai, ça a permis de supprimer une erreure qui arivait de temps en temps a savoir: si je mettai un sleep a 1 (pour simuler le lancement d'un job) la hiérarchisation ne fonctionnait plus.
 
Encore merci !
Cordialement,
Benjamin Pleumeckers.
 
Pour les curieux, voici le code:
 

Code :
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use Data::Dumper;
  6. use Parallel::ForkManager;
  7. use IPC::Shareable;
  8. ####################### PACKAGES ###########################
  9. package Job;
  10. my @listJob = ();
  11. my @tabProc = ();
  12. sub new {
  13. my ($class, $ID_PROCESS, $ALIAS, $PERE, $FILS, $LOCK, $TYPE, $STARTED) = @_;
  14. my $this = {};
  15. bless($this, $class);
  16. $this->{ID_PROCESS} = $ID_PROCESS;
  17. $this->{ALIAS} = $ALIAS;
  18. $this->{PERE} = $PERE;
  19. $this->{FILS} = $FILS;
  20. $this->{LOCK} = $LOCK;
  21. $this->{TYPE} = $TYPE;
  22. $this->{STARTED} = $STARTED;
  23. push(@listJob,$ID_PROCESS);
  24. push(@tabProc,$this);
  25. return $this;
  26. }
  27. sub getID {
  28. my ($this) = @_;
  29. return $this->{ID_PROCESS};
  30. }
  31. sub getAlias {
  32. my ($this) = @_;
  33. return $this->{ALIAS};
  34. }
  35. sub getPere {
  36. my ($this) = @_;
  37. return $this->{PERE};
  38. }
  39. sub getFils {
  40. my ($this) = @_;
  41. return $this->{FILS};
  42. }
  43. sub getLock {
  44. my ($this) = @_;
  45. return $this->{LOCK};
  46. }
  47. 1;
  48. ####################### FIN PACKAGES ###########################
  49. ####################### MAIN ###########################
  50. my $pere;
  51. my $fils;
  52. my $LEVEL=0;
  53. $pere = undef;
  54. $fils = "4,5";
  55. my $proc1 = new Job( "1", "alias1", $pere, $fils, "0", "unknown", "0" );
  56. $pere = undef;
  57. $fils = "6";
  58. my $proc2 = new Job( "2", "alias2", $pere, $fils, "0", "unknown", "0" );
  59. $pere = undef;
  60. $fils = "8,9";
  61. my $proc3 = new Job( "3", "alias3", $pere, $fils, "0", "unknown", "0" );
  62. $pere = "1";
  63. $fils = "7";
  64. my $proc4 = new Job( "4", "alias4", $pere, $fils, "0", "unknown", "0" );
  65. $pere = "1";
  66. $fils = "7";
  67. my $proc5 = new Job( "5", "alias5", $pere, $fils, "0", "unknown", "0" );
  68. $pere = "2";
  69. $fils = "8";
  70. my $proc6 = new Job( "6", "alias6", $pere, $fils, "0", "unknown", "0" );
  71. $pere = "4,5";
  72. $fils = "8";
  73. my $proc7 = new Job( "7", "alias7", $pere, $fils, "0", "unknown", "0" );
  74. $pere = "7,6,3";
  75. $fils = undef;
  76. my $proc8 = new Job( "8", "alias8", $pere, $fils,, "0", "unknown", "0" );
  77. $pere = "3";
  78. $fils = undef;
  79. my $proc9 = new Job( "9", "alias9", $pere, $fils, "0", "unknown", "0" );
  80. print "listJob : @listJob\n";
  81. print Data::Dumper::Dumper @tabProc;
  82. foreach my $row (@tabProc)
  83. {
  84.  if ($row->{PERE} eq undef)
  85.  {
  86.   $row->{PERE} = "NULL";
  87.  }else
  88.  {
  89.   $row->{PERE} =~ s/,/ /g;
  90.  }
  91.  if ($row->{FILS} eq undef)
  92.  {
  93.   $row->{FILS} = "NULL";
  94.  }
  95.  else
  96.  {
  97.   $row->{FILS} =~ s/,/ /g;
  98.  }
  99.  if ($row->{PERE} eq "NULL" )
  100.  {
  101.   $row->{TYPE} = "PERE-0";
  102.  }
  103.  else
  104.  {
  105.   if ($row->{FILS} eq "NULL" )
  106.   {
  107.    $row->{TYPE} = "FILS";
  108.   }
  109.   else
  110.   {
  111.    $row->{TYPE} = "PERE";
  112.   }
  113.   $row->{STARTED} = 0;
  114.  }
  115.  $LEVEL+=1;
  116. }
  117. print Data::Dumper::Dumper @tabProc;
  118. print "LEVEL : $LEVEL\n";
  119. my $RETOUR;
  120. my @tabProc_temp=();
  121. my @tabProcEnCours;
  122. my @tabProcFini;
  123. #my $i=0;
  124. my %options = (
  125. create    => 1,
  126. exclusive => 0,
  127. mode      => 0644,
  128. destroy   => 0,
  129. );
  130. print "tabProcFini: @tabProcFini\n";
  131. print "tabProcEnCours: @tabProcEnCours\n";
  132. print "tabProc_temp: @tabProc_temp\n";
  133. tie @tabProc_temp, 'IPC::Shareable', 'tie1', \%options;
  134. tie @tabProcEnCours, 'IPC::Shareable', 'tie2', \%options;
  135. tie @tabProcFini, 'IPC::Shareable', 'tie3', \%options;
  136. @tabProcEnCours=();
  137. @tabProcFini=();
  138. @tabProc_temp=@tabProc;  #tabProc_temp contient la copie de la liste des processus existants.
  139. print "tabProc_temp: @tabProc_temp\n";
  140. my $pm = new Parallel::ForkManager(10);
  141. while( @tabProc_temp )  #Tant que le tableau des processus n'est pas vide
  142. {
  143.  #$i=0;
  144.  foreach my $row (@tabProc_temp)  #pour chaque processus
  145.  {
  146.   my $ID = $row->{ID_PROCESS};
  147.   my $LOCK = $row->{LOCK};
  148.   my $TYPE = $row->{TYPE};
  149.   my $PERE = $row->{PERE};
  150.   print "tabProcFini : @tabProcFini\n";
  151.   print "tabProcEnCours : @tabProcEnCours\n";
  152.   print "PROCESS $ID lets work on it! \n";
  153.   my %hashEncours = map{$_ => 1} (@tabProcEnCours);
  154.   if (exists $hashEncours{$ID})  #si le processus est en cour de traitemet
  155.   {
  156.    print "PROCESS $ID already forked! \n";
  157.    print "PROCESS ","$ID Let's try another process \n\n";
  158.   }else
  159.   {
  160.    if ($LOCK == "0" ) #si le processus est bloqué (dans ce test code, il ne l'est jamais)
  161.    {
  162.     $RETOUR = "Not OK";
  163.     if ($RETOUR eq "OK" ) #si le retout est OK (dans ce test code, il ne l'est jamais)
  164.     {
  165.      print "PROCESS","$ID is Running \n";
  166.      push(@tabProcFini,$ID);
  167.      print "\n";
  168.     }
  169.     else
  170.     {
  171.      print "PROCESS ","$ID is Stopped \n";
  172.      if ($TYPE eq "PERE-0" ) #si le processus en cour de traitement est tout en haut de l'arbre (donc que lui meme n'a pas de pere)
  173.      {
  174.       $pm->start and next; # je lance un fork
  175.       my $ID_inFork = $ID;
  176.       (tied @tabProcEnCours)->shlock;
  177.       push(@tabProcEnCours,$ID_inFork);  #j'ajoute le processus dans le tableau des processus en cour de traitement
  178.       (tied @tabProcEnCours)->shunlock;
  179.       sleep 1;  # je fais un sleep pour simuler le temps de traitement du processus
  180.       (tied @tabProc_temp)->shlock;
  181.        my @indextoremove = ();
  182.        foreach my $row_inFork (0..$#tabProc_temp) {
  183.         push(@indextoremove, $row_inFork) if ($tabProc_temp[$row_inFork]->{ID_PROCESS} == $ID_inFork )
  184.        }
  185.        foreach ((reverse @indextoremove)) {
  186.         splice(@tabProc_temp, $_, 1);
  187.        }
  188.       (tied @tabProc_temp)->shunlock;
  189.       (tied @tabProcFini)->shlock;
  190.        push(@tabProcFini,$ID_inFork);  # j'ajoute le processus dans le tableau contenant les processus fini
  191.       (tied @tabProcFini)->shunlock;
  192.       (tied @tabProcEnCours)->shlock;
  193.        my %hashTabProcEnCours = map{$_ => 1} (@tabProcEnCours);
  194.        delete $hashTabProcEnCours{$ID_inFork};
  195.        @tabProcEnCours=keys(%hashTabProcEnCours);
  196.       (tied @tabProcEnCours)->shunlock;
  197.       print "PROCESS ","$ID_inFork well started outside \n\n";
  198.       $pm->finish;
  199.      }else
  200.      {
  201.       my @tab1 = split(/ /,$PERE);
  202.       my $tailletab1 = scalar @tab1;
  203.       my @tab2=@tabProcFini;
  204.       my %hash = map{$_ => 1} (@tab1, @tab2);
  205.       my @tab = keys %hash;
  206.       my $nombre_elements_commun = @tab1 + @tab2 - @tab;
  207.       if($nombre_elements_commun == $tailletab1)
  208.       {
  209.        $pm->start and next; # je lance un fork
  210.        my $ID_inFork = $ID;
  211.        my $PERE_inFork =$PERE;
  212.        (tied @tabProcEnCours)->shlock;
  213.         push(@tabProcEnCours,$ID_inFork); #j'ajoute le processus dans le tableau des processus en cour de traitement
  214.        (tied @tabProcEnCours)->shunlock;
  215.        print "PROCESS ","$ID_inFork Parents: $PERE_inFork \n";
  216.        print "PROCESS ","$ID_inFork Les elements de la liste \"PERE\" du process $ID_inFork sont tous présents dans le tableau \@tabProcFini \n\n";
  217.        sleep 1; # je fais un sleep pour simuler le temps de traitement du processus
  218.        (tied @tabProc_temp)->shlock;
  219.         my @indextoremove = ();
  220.         foreach my $row_inFork (0..$#tabProc_temp) {
  221.          push(@indextoremove, $row_inFork) if ($tabProc_temp[$row_inFork]->{ID_PROCESS} == $ID_inFork )
  222.         }
  223.         foreach ((reverse @indextoremove)) {
  224.          splice(@tabProc_temp, $_, 1);
  225.         }
  226.        (tied @tabProc_temp)->shunlock;
  227.        (tied @tabProcFini)->shlock;
  228.         push(@tabProcFini,$ID_inFork);  # j'ajoute le processus dans le tableau contenant les processus fini
  229.        (tied @tabProcFini)->shunlock;
  230.        (tied @tabProcEnCours)->shlock;
  231.         my %hashTabProcEnCours = map{$_ => 1} (@tabProcEnCours);
  232.         delete $hashTabProcEnCours{$ID_inFork};
  233.         @tabProcEnCours=keys(%hashTabProcEnCours);
  234.        (tied @tabProcEnCours)->shunlock;
  235.        print "PROCESS ","$ID_inFork well started inside\n\n";
  236.        $pm->finish;
  237.       }else
  238.       {
  239.        print "PROCESS ","$ID Les elements de la liste \"PERE\" du process $ID NE sont PAS tous présents dans le tableau \@tabProcFini \n";
  240.        print "PROCESS ","$ID Let's try another process \n\n";
  241.       }
  242.      }
  243.      $RETOUR = "OK";
  244.      if ($RETOUR ne "OK" )
  245.      {
  246.      print "PROCESS","$ID not started \n";
  247.      exit(1);
  248.      }
  249.     }
  250.    }
  251.    else
  252.    {
  253.     print "PROCESS","$ID is Locked !!! \n";
  254.     push(@tabProcFini,$ID);
  255.     print "\n";
  256.    }
  257.   }
  258.   sleep 1;
  259.   #$i++;
  260.   #print "tabProc_temp : \n";
  261.   #print Data::Dumper::Dumper @tabProc_temp;
  262.  }
  263. }
  264. $pm->wait_all_children;
  265. print "tabProc_temp : \n";
  266. print Data::Dumper::Dumper @tabProc_temp;
  267. print "tabProcFini : @tabProcFini\n";
  268. print "tabProcEnCours : @tabProcEnCours\n\n";

Reply

Marsh Posté le 19-12-2011 à 11:48:01    

Excellent!  
C'était codé sans visibilité (je suis sous un environnement Windows ou certains modules ne sont pas disponibles) et je ne pouvais donc pas tester ce code.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed