2

寻找一种方法,如何按照另一个列表定义的顺序从哈希中获取值。

“演示”代码(实际值不同):

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.
4

1 回答 1

7

定义@order后,定义%order_h:

my %order_h;
my $i = 0;
$order_h{$_} = $i++ for @order;

然后,而不是关于排序的评论,添加这一行:

@list = sort { $order_h{$a} <=> $order_h{$b} } @list;

这是整个代码的清理版本:

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;
    say join '/', @keys ? @{$href}{ @keys } : 'xx';
}
于 2012-09-14T15:05:10.373 回答