我在哈希数据结构中存储了多个具有相同长度的字符串。 示例:
$VAR1 = {
'first' => 'abcXY',
'second' => 'XYXYa',
'third' => '*abXZ'
};
从这个'矩阵'对于字符,我想删除'列'它只包含字符X
或Y
。在上面的例子中,这将是每个字符串的第四个字符(第4个'列')。
期望的结果是:
$VAR1 = {
'first' => 'abcY',
'second' => 'XYXa',
'third' => '*abZ'
};
以下代码通过创建哈希结构值的转置,然后确定要保留哪些索引来实现此目的:
# data structure
my %h = ('first'=>'abcXY', 'second'=>'XYXYa', 'third'=>'*abXZ' );
# get length of all values in hash
my $nchar = length $h{(keys(%h))[0]};
# transpose values of hash
my @transposed = map { my $idx=$_; [map {substr ($_, $idx, 1) } values(%h)] } 0..$nchar-1;
# determine indices which I want to keep
my @indices;
for my $i (0..$#transposed){
my @a = @{$transposed[$i]};
# do not keep index if column consists of X and Y
if ( scalar(grep {/X|Y/} @a) < scalar(@a) ) {
push @indices, $i;
}
}
# only keep letters with indices
for my $k (keys %h){
my $str = $h{$k};
my $reduced = join "", map{ substr ($str, $_, 1) } @indices;
$h{$k} = $reduced;
}
这是一个非常简单的操作代码。我怎么能更优雅地做到这一点(最好不要使用一些矩阵库,但使用标准的perl)?
修改
这是另一个示例:从以下字符串开始,应删除第一个和最后一个字符,因为在两个字符串中,第一个和最后一个位置是X
或Y
:
$VAR1 = {
'1' => 'Xsome_strX',
'2' => 'YsomeXstrY'
};
期望的结果:
$VAR1 = {
'1' => 'some_str',
'2' => 'someXstr'
};
答案 0 :(得分:1)
my $total = values %hash;
my %ind;
for my $v (values %hash) {
$ind{ pos($v) -1 }++ while $v =~ /[XY]/g;
}
my @to_remove = sort {$b <=> $a} grep { $ind{$_} == $total } keys %ind;
for my $v (values %hash) {
substr($v, $_, 1, "") for @to_remove;
}