Me encuentro con ganas de usar formas de iteración modificador de declaración sobre hashes en Perl (v5):

my %h = (...);
do_something($_[0], $_[1]) for each %h;  ### $_[0] => key, $_[1] => val

O:

my %h = (...);
my @ary = %h;
do_something($_[0], $_[1]) for splice(@ary, 0, 2);

Por supuesto, ninguna de estas formas existe. ¿Solo tiene curiosidad si ha habido algún trabajo para apoyar el uso de splice o each con la forma de modificador de declaración de for? ¿En Perl 6 o, a través de backport, v5?

2
textral 9 sep. 2018 a las 11:22

3 respuestas

La mejor respuesta

Hay algunas funciones excelentes en List :: Util y List :: MoreUtils para ayudar con situaciones como esta. En particular, eche un vistazo a pairs:

use List::Util qw{pairs};

do_something($_->[0], $_->[1]) foreach pairs %h;

O si puedes soportar un mapa en un contexto vacío:

use List::Util qw{pairmap};

pairmap { do_something($a, $b) } %h;
2
mwp 9 sep. 2018 a las 11:00

La solución más limpia es la siguiente:

do_something($_, $h{$_}) for keys %h;

Si desea ahorrar memoria, puede usar each como de costumbre.

{ my ($k, $v);  do_something($k, $v) while ($k, $v) = each(%h); }

Por supuesto, es mucho más limpio sin usar un modificador de declaración.

while (my ($k, $v) = each(%h)) { do_something($k, $v); }

Finalmente, si no está tratando con un hash, podría usar pairs de Lista :: Util.

use List::Util qw( pairs );

do_something(@$_) for pairs %h;

Este último enfoque es muy derrochador ya que crea de manera ineficiente una multitud de matrices.

2
ikegami 11 sep. 2018 a las 03:51

Puedes acortar

{my ($k, $v);  do_something($k, $v) while ($k, $v) = each(%h); }

Para

do_something($a, $b) while ($a, $b) = each %h;

Como $ a y $ b ya están declarados para ordenar.

0
user10688008 21 nov. 2018 a las 21:01