perl – 如何根据另一个哈希的键/值删除[sub]哈希?
让我们假设我有两个哈希.其中一个包含一组数据,只需要保留显示在另一个哈希中的内容.
例如 my %hash1 = ( test1 => { inner1 => { more => "alpha",evenmore => "beta" } },test2 => { inner2 => { more => "charlie",somethingelse => "delta" } },test3 => { inner9999 => { ohlookmore => "golf",somethingelse => "foxtrot" } } ); my %hash2 = ( major=> { test2 => "inner2",test3 => "inner3" } ); 我想要做的是删除hash1中的整个subhash,如果它不作为hash2 {major}中的键/值存在,最好没有模块. “innerX”中包含的信息无关紧要,只需要保持不变(除非删除子哈希然后它就会消失). 在上面的示例中,在执行此操作之后,hash1将如下所示: my %hash1 = ( test2 => { inner2 => { more => "charlie",); 它删除hash1 {test1}和hash1 {test3},因为它们与hash2中的任何内容都不匹配. 这是我目前尝试过的,但它不起作用.也不是最安全的事情,因为我在尝试从中删除哈希时循环哈希.但是我在每个都删除应该没问题? 这是我尝试这样做的,但是perl抱怨: 在使用“严格参考”时,不能使用字符串(“inner1”)作为HASH参考 while(my ($test,$inner) = each %hash1) { if(exists $hash2{major}{$test}{$inner}) { print "$test($inner) is in exists.n"; } else { print "Looks like $test($inner) does not exist,REMOVING.n"; #not to sure if $inner is needed to remove the whole entry delete ($hash1{$test}{$inner}); } } 解决方法
你很亲密请记住,$hash2 {major} {$test}是一个标量,而不是哈希引用.
#! /usr/bin/perl use strict; use warnings; my %hash1 = ( test1 => { inner1 => { more => "alpha",somethingelse => "foxtrot" } } ); my %hash2 = ( major => { test2 => "inner2",test3 => "inner3" } ); foreach my $k (keys %hash1) { my $delete = 1; foreach my $inner (keys %{ $hash1{$k} }) { $delete = 0,last if exists $hash2{major}{$k} && $hash2{major}{$k} eq $inner; } delete $hash1{$k} if $delete; } use Data::Dumper; $Data::Dumper::Indent = 1; print Dumper %hash1; 以$delete = 0开头的行,…有点可爱.它相当于$delete = 0;持续;在另一个条件内,但它已经嵌套了两次.不想建立一个matryoshka doll,我使用了statement modifier,但顾名思义,它修改了一个语句. 这就是Perl’s comma operator的用武之地:
在这种情况下,左参数是表达式$delete = 0,右参数是最后一个. 条件似乎不必要地挑剔,但是 ... if $hash2{major}{$k} eq $inner; 在探测%hash2(例如test1 / inner1)中未提及的测试时,会产生未定义值警告.运用 .. if $hash2{major}{$k} && $hash2{major}{$k} eq $inner; 如果“内部名称”是一个假值,如字符串“0”,则会错误地删除%hash2中提到的测试.是的,使用存在这里可能是不必要的挑剔,但不知道你的实际哈希键,我选择了保守的路线. 输出: $VAR1 = { 'test2' => { 'inner2' => { 'somethingelse' => 'delta','more' => 'charlie' } } }; 虽然您没有违反它,但请注意以下与使用
更新:搜索哈希就像它们是数组一样(通过说“…线性而不是对数”来打动你的CS书呆子朋友)是一个红旗,上面的代码就是这样.一个更好的方法,结果类似于Penfold的答案,是 %hash1 = map +($_ => $hash1{$_}),grep exists $hash2{major}{$_} && exists $hash1{$_}{ $hash2{major}{$_} },keys %hash1; 在很好的声明式样式中,它描述了%hash1的所需内容,即 >%hash1的第一级键应该在$hash2 {major}中提及,和 (哇,令人目不暇接.我们需要英文多个占位符变量!) ($_ => $hash1 {$_})中的一元加值消除了可怜的解析器的歧义,因此它知道我们希望将表达式视为“对”.如果有必要,请参阅perlfunc documentation on (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |