2015-01-14 2 views
0

해시 데이터 구조에 저장된 길이가 같은 여러 문자열이 있습니다. 예 : 문자의 '매트릭스'에서패턴에 따라 Perl이 문자열 행렬에서 문자를 제거합니다.

$VAR1 = { 
      'first' => 'abcXY', 
      'second' => 'XYXYa', 
      'third' => '*abXZ' 
     }; 

, 나는 독점적으로 문자 X 또는 Y를 포함하는 '열'을 제거하고 싶습니다. 위의 예에서이 문자열은 각 문자열의 네 번째 문자 (네 번째 '열')입니다. 원하는 결과가 될 것이다 :

$VAR1 = { 
      'first' => 'abcY', 
      'second' => 'XYXa', 
      'third' => '*abZ' 
     }; 

다음 코드 내 해시 구조 값의 전치를 생성하여이를 수행하고 유지와 indices 결정 :

# 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; 
} 

이것은 끔찍한 양 간단한 조작을위한 코드. 어떻게하면 좀 더 우아하게 할 수 있습니까? (어떤 행렬 라이브러리가 아닌, 표준 펄을 사용하는 것이 더 바람직합니까?)

편집 여기

또 다른 예 :

$VAR1 = { 
      '1' => 'Xsome_strX', 
      '2' => 'YsomeXstrY' 
     }; 
: 두 문자열에서, 첫 번째와 마지막 위치 중 하나 X 또는 Y 때문에 다음 문자열에서 첫 번째와 마지막 문자를 제거한다

원하는 결과 :

$VAR1 = { 
      '1' => 'some_str', 
      '2' => 'someXstr' 
     }; 

답변

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; 
} 
+0

그러나 이것은 제거하려는 네 번째 열임을 알고 있다고 가정합니다. 위는 단지 예일뿐입니다. 'X' 또는'Y' 만 포함하는 모든 열을 찾아서이 열을 제거하고 싶습니다. – user1981275

+0

또 다른 예제 @ Сухой27을 추가했습니다. – user1981275

+0

이것은 나를 위해 작동하지 않습니다. @ Сухой27 :'빼기 (-)에서 초기화되지 않은 값 사용 '... – user1981275

관련 문제