Combining some of these ideas, I came up with the following
make_sort_sub:
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{ say };
use Scalar::Util qw{ looks_like_number };
sub make_sort_sub {
my $code = shift;
my $hashref = shift;
my $sort_sub = eval "sub { $code }";
die $@ if $@;
return $sort_sub;
}
# simple code snippet
my %hash = ( a => 5, b => 4, c => 3, d => 5, e => 4 );
my $keys_by_value = make_sort_sub(
'$hashref->{$a} <=> $hashref->{$b}',
\%hash);
my @keys_sorted_by_value = sort $keys_by_value keys %hash;
say @keys_sorted_by_value;
# Try with curlies now
$keys_by_value = make_sort_sub(
'{$hashref->{$a} <=> $hashref->{$b}}',
\%hash);
@keys_sorted_by_value = sort $keys_by_value keys %hash;
say @keys_sorted_by_value;
# Naive compare by values as numbers, keys as strings
my $keys_by_value_or_keys = make_sort_sub(
'$hashref->{$a} <=> $hashref->{$b} or $a cmp $b',
\%hash);
my @keys_by_value_or_keys = sort $keys_by_value_or_keys keys %hash;
say @keys_by_value_or_keys;
# Compare as numbers then strings, values then keys
my %hash2 = (a => 'a', b => 'b', c => 3, d => 4);
my $keys_by_value_or_keys_mixed = make_sort_sub(
'return $hashref->{$a} <=> $hashref->{$b}
if ((looks_like_number($hashref->{$a}) and looks_like_number(
+$hashref->{$b}))
and ($hashref->{$a} <=> $hashref->{$b}));
return $hashref->{$a} cmp $hashref->{$b}
if ($hashref->{$a} cmp $hashref->{$b});
return $a <=> $b
if ((looks_like_number($a) and looks_like_number($b)) and ($a
+<=> $b));
return $a cmp $b;',
\%hash2);
my @keys_by_value_or_keys_mixed = sort $keys_by_value_or_keys_mixed ke
+ys %hash2;
say @keys_by_value_or_keys_mixed;
exit;
Output:
cbeda
cbeda
cbead
cdab
I couldn't figure out a good way to include a real code block, because it couldn't reference the keys and values. Choroba's suggestion is nice, but can't really handle anything other than $a/$b (AFAIK). Chicken and egg.
As an aside, I can't remember if there's a nice CPAN way to do the last sub ("keys by value or by keys, numbers or strings").
-QM
--
Quantum Mechanics: The dreams stuff is made of
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.