Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在perl中以哈希格式编写交换键和值的最简洁的方法_Perl - Fatal编程技术网

在perl中以哈希格式编写交换键和值的最简洁的方法

在perl中以哈希格式编写交换键和值的最简洁的方法,perl,Perl,我想通过在perl中交换散列中的键和值来创建一个新的散列。注意,这样做的目的是将重复值的键放入一个数组中,这与reverse所做的不同 很明显,我可以做一个循环。但是我不确定是否可以用一种紧凑的形式,比如使用map等 谢谢。你可以做这样一个“紧凑”的循环 my %orig = # whatever my %rev; push @{$rev{$orig{$_}}}, $_ for keys %orig; 请注意,“反向”散列的所有值都将是具有此功能的数组。是否像这样工作 my %orig = (

我想通过在perl中交换散列中的键和值来创建一个新的散列。注意,这样做的目的是将重复值的键放入一个数组中,这与
reverse
所做的不同

很明显,我可以做一个循环。但是我不确定是否可以用一种紧凑的形式,比如使用
map

谢谢。

你可以做这样一个“紧凑”的循环

my %orig = # whatever
my %rev;
push @{$rev{$orig{$_}}}, $_ for keys %orig;
请注意,“反向”散列的所有值都将是具有此功能的数组。

是否像这样工作

my %orig = ( 1 => 'a', 2 => 'b', 3 => 'c', 65 => 'a' );
my $new_hash = List::Util::reduce { push @{ $a->{$orig{$b}} }, $b; $a } {}, keys %orig;
出于某种原因,在散列解引用中包装reduce调用似乎打破了&-prototype的魔力,但您可以通过以下方式避免新变量:

%orig = %{ List::Util::reduce sub { push @{ $a->{$orig{$b}} }, $b; $a }, {}, keys %orig };
如果要避免对%orig的内部引用,请假设原始哈希是来自其他表达式的结果,假设perl具有成对列表:

%orig = %{ List::Util::reduce sub { push @{ $a->{ $b->[0] } }, $b->[1]; $a }, {},
    @{ List::Util::reduce sub { ! @$a || $#{ $a->[-1] } ? push @$a, [ $b ] : push @{ $a->[-1] }, $b; $a }, [],
        reverse %orig
    }
};
具有一些实用功能的更漂亮:

sub flatten_hashref { %{$_[0]} }
sub flatten_arrayref { @{$_[0]} }
sub pairlist { reduce { ! @$a || $#{ $a->[-1] } ? push @$a, [ $b ] : push @{ $a->[-1] }, $b; $a } [], @_ }

%orig =
    flatten_hashref
    reduce { push @{ $a->{ $b->[0] } }, $b->[1]; $a } {},
    flatten_arrayref
    pairlist
    reverse
    %orig;

定义“契约”;然后告诉我们为什么这是一个值得称赞的目标。在我的评分册上,短小且不可读的内容会让你失去分数。@tchrist:我的意思是“更实用”。我相信避免显式循环可以在matlab、R、python以及perl等语言中获得一些效率。也许不是所有的情况,但通常都是这样。我说得对吗?不,不对。如果代码对您更有意义,而不是为了提高效率,请这样做。谢谢。这就是我在循环方法中所说的。我想问的是:我可以一次性声明一个新的散列,还是不显式声明一个新的散列,就像
%orig=map{$orig{$\u}=>$\ u}键(%orig)?我不知道有一个。声明新哈希有什么问题?