我有两个关联的数组。第一个具有哈希中的“关键”,第二个具有“值”。数组中每个“键”有多个实例,与每个键关联的值可以是yes或no。一个简单的例子:
@1 = ('NET1020, NET0190, NET1020, NET0230,
NET1020, NET1639, NET0820, NET1639');
@2 = ('yes, yes, no, no,
yes, no, yes, no');
请注意,“密钥”NET1020有“是”和“否”值。
我需要使用@ 1到1st查找重复项并从两个数组中删除它们,如果其中一个值在@ 2中为no,那么它必须是@ 1中“key”的值。如果没有,那么值可以是。基本上我最终需要的是:
%1-2 = (
"NET1020" => "No",
"NET0190" => "Yes",
"NET0230" => "No",
"NET1639" => "No",
"NET0820" => "Yes",
);
我希望我在解释中已经足够清楚了。我是一个perl新手,我甚至不知道从哪里开始。
谢谢你的帮助。
答案 0 :(得分:2)
my @names = split /\s*,\s*/, 'NET1020, NET0190, NET1020, NET0230, NET1020, NET1639, NET0820, NET1639';
my @flags = map { $_ eq 'yes' }
split /\s*,\s*/, 'yes, yes, no, no, yes, no, yes, no';
my %flags;
for (0..$#names) {
if (exists($flags{ $names[$_] })) {
$flags{ $names[$_] } &&= $flags[$_];
} else {
$flags{ $names[$_] } = $flags[$_];
}
}
print($_, ": ", $flags{$_} ? "Yes" : "No", "\n")
for sort keys %flags;
您不应该使用yes
和no
或Yes
和No
。此解决方案将yes
和no
转换为更合适的true和false输入。如果你想输出Yes
和No
为true和false,你可以在输出上处理它,如图所示。
您甚至可以在这项小工作中看到使用真与假的好处。它通过ANDing具有相同名称的条目的标志来工作。 (当ANDing时,False胜出。当ORing时,True胜出。)
答案 1 :(得分:0)
数组内容的顺序是否重要?
如果没有,我建议使用哈希:
my %hash = ();
for my $i (0 .. $#array1)
{
$hash{ $array1[$i] } = $array2[$i];
}
@filtered1 = keys %hash;
@filtered2 = values %hash;
注意:代码未经测试且未经过验证
答案 2 :(得分:0)
只需遍历这些值,然后根据需要添加/更新哈希值。
1.如果密钥已存在,只有在现有值不是“否”时才更新
2如果密钥不存在,请将其添加到哈希
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @arr1 =
qw(NET1020 NET0190 NET1020 NET0230 NET1020 NET1639 NET0820 NET1639);
my @arr2 =
qw(yes yes no no yes no yes no);
my %h;
KEY:
foreach my $i ( 0 .. $#arr1 ) {
# get the values out of your parallel arrays
my $key = $arr1[$i];
my $val = $arr2[$i];
# if the key is already in your hash and does not have this value
if (exists $h{$key} && $h{$key} ne $val) {
# don't change the key if the value is currently 'no'
next KEY if lc $h{$key} eq 'no';
# update if the value was not yes, meaning this is going from yes -> no
$h{$key} = $val;
}
# if the key didn't exist already add it
$h{$key} = $val;
}
print Dumper \%h;
__END__
{ 'NET0190' => 'yes',
'NET1639' => 'no',
'NET0230' => 'no',
'NET0820' => 'yes',
'NET1020' => 'no'
};
如果没有重复项,您可以使用hash-slice在一行中执行此操作:
my %h;
@h{@arr1} = @arr2;
答案 3 :(得分:0)
我必须修改你的列表才能更好地用作Perl。你给了一个多行字符串而不是数组。基本上,我的方法是非常标准的CPAN。 List::Util
和List::MoreUtils
。
zip
在列表之间创建基于订单的对应关系。 pairs
允许您将键值对作为( $a, $b )
处理。
use strict;
use warnings;
use List::Util qw<pairmap>;
use List::MoreUtils qw<zip>;
my @_1 = split /,\s*/ms,
('NET1020, NET0190, NET1020, NET0230,
NET1020, NET1639, NET0820, NET1639')
;
my @_2 = split /,\s*/ms,
('yes, yes, no, no,
yes, no, yes, no')
;
my %hash;
pairmap {
$hash{ $a } = $b unless ( $hash{ $a } // '' ) eq 'no';
} zip @_1, @_2
;
当然,pairwise
可能更清洁:
use List::MoreUtils qw<pairwise>;
...
pairwise {
$hash{ $a } = $b unless ( $hash{ $a } // '' ) eq 'no';
} @_1, @_2
;
答案 4 :(得分:0)
目前尚不清楚您是从Perl数组开始还是以逗号分隔的简单字符串开头。我也不确定您是否希望结果哈希值在显示时大写,或者与输入值相同。
这个简短的程序将满足您的需求。它只使用@a1
中的每个键和初始值yes
来分配哈希元素。此后,如果在no
中遇到相应的@a2
,则该元素的值将设置为no
。
use strict;
use warnings;
my @a1 = qw{ NET1020 NET0190 NET1020 NET0230 NET1020 NET1639 NET0820 NET1639 };
my @a2 = qw{ yes yes no no yes no yes no };
my %data;
for my $i (0 .. $#a1) {
my $key = $a1[$i];
$data{$key} = 'yes' unless $data{$key};
$data{$key} = 'no' if $a2[$i] eq 'no';
}
use Data::Dump;
dd \%data;
<强>输出强>
{
NET0190 => "yes",
NET0230 => "no",
NET0820 => "yes",
NET1020 => "no",
NET1639 => "no",
}