別のリストで定義された順序で、ハッシュから値を取得する方法を探しています。
「デモ」コード(実際の値は異なります):
use 5.014;
use warnings;
my $href = {
'Long one' => 'v1',
'xxx two' => 'v2',
'another3' => 'v3',
'xfour' => 'v4',
'some5' => undef,
};
#keys from the $href in defined order
my @order = ('Long one', 'xfour', 'nono', 'another3', 'some5', 'xxx two');
#in the real code:
#my $href = some_sub(......); my @order = another_sub(....);
#cleanup the @order form undefined values
@order = grep { exists $href->{$_} && defined $href->{$_} } @order;
#my input
while(<DATA>) {
chomp;
#filter out nonexistent keys and undefined values
my @defined_data = grep { exists $href->{$_} && defined $href->{$_} } split '/';
my $str = "xx";
$str = join('/',
map { $href->{$_} } some_my_sort(@defined_data)
) if @defined_data;
say $str;
}
sub some_my_sort {
my(@list) = @_;
# "somewhat"sort the @list in order defined by @order
# haven't any idea how to do this :(
# __HERE NEED HELP__ to sort the @list, to the order defined in the @order
#and get only first two values. if exists only one value, return only one
if($#list > 0) {
return ($list[0], $list[1]);
}
else {
return($list[0]);
}
}
__DATA__
another3/some5/Long one/xfour/xxx two
xxx two/blabla/some5/another3/xfour
some5
notexists/some5/xxx two/Long one
some5/another3
上記の入力の場合、次の出力を取得します。
v1/v4
v4/v3
xx
v1/v2
v3
@ikegamiソリューションを形成する:
use 5.014;
use warnings;
my $href = { 'Long one' => 'v1', 'xxx two' => 'v2', 'another3' => 'v3', 'xfour' => 'v4', 'some5' => undef, };
my @order = ('Long one', 'xfour', 'nono', 'another3', 'some5', 'xxx two');
@order = grep { exists $href->{$_} && defined $href->{$_} } @order;
my %order = map { $order{$_} => $_ } 0..$#order;
while (<DATA>) {
chomp;
my @keys = grep { defined $href->{$_} } split '/';
@keys = sort { $order{$a} <=> $order{$b} } @keys;
splice(@keys, 2) if @keys > 2;
@keys = 'xx' if !@keys;
say join '/', @{$href}{ @keys };
}
次の-エラー-を取得し、その理由を本当に理解していません:
Global symbol "%order" requires explicit package name at ike line 8.
Execution of ike aborted due to compilation errors.