2010-10-22 17 views
6

estoy usando sort con una subrutina comparación personalizado que he escrito:¿Puedo pasar argumentos a la subrutina de comparación de tipo en Perl?

sub special_compare { 
# calc something using $a and $b 
# return value 
} 

my @sorted = sort special_compare @list; 

Sé que es mejor uso $a$b y que se ajusta automáticamente, pero a veces me gustaría que mi special_compare para obtener más argumentos, es decir:

sub special_compare { 
my ($a, $b, @more) = @_; # or maybe 'my @more = @_;' ? 
# calc something using $a, $b and @more 
# return value 
} 

¿Cómo puedo hacer eso?

Respuesta

11

Utilice la sintaxis sort BLOCK LIST, consulte perldoc -f sort.

Si ha escrito el special_compare sub anterior, se puede hacer, por ejemplo:

my @sorted = sort { special_compare($a, $b, @more) } @list; 
+0

+1 ¡agradable y simple! –

+3

Es posible que desee pasar una referencia a '@ more' para evitar que se copie todo el tiempo. –

+0

O simplemente use el código en línea en lugar de llamar a un sub, si corresponde. – mscha

3

Puede utilizar el cierre en lugar de la subrutina para ordenar:

my @more; 
my $sub = sub {   
    # calc something using $a, $b and @more 
}; 

my @sorted = sort $sub @list; 

Si desea pasar los elementos que se compararán en @_, establecen el prototipo de subrutina en ($$). Nota: esto es más lento que la subrutina sin prototipo.

+0

La solución de mscha es más limpia y parece funcionar. ¿Ves alguna razón para no usarlo? –

+0

@David: usar el cierre puede ser más eficiente. Aunque no ejecuté un punto de referencia. –

+2

Si el rendimiento es una consideración y la función de comparación es pesada, eche un vistazo a la [Transformada de Schwartzian] (http://en.wikipedia.org/wiki/Schwartzian_transform). – mscha

Cuestiones relacionadas