2013-07-29 2 views
0

다음 해시가 있으며 가장 큰 해시 값 64 사이의 중복 항목을 찾아야합니다. 나는 쓸모없는 몇 가지 해결책을 시도해 보았고 Perl 문법을 익숙하게하지 않아도 작동하도록 만들었다.해시에서 중복 된 항목 찾기, 새 해시로 그룹화 된 저장

내가

$VAR1 = { 
    '6' => [ '1000', '2000', '4000' ], 
    '4' => [ '1000', '2000', '3000' ] 
}; 

해시를 가지고있는 해시 내가 예를 들어, 모든 공통 요소를 찾아

$VAR1 = { 
    '6' => ['4000'], 
    '4' => ['3000'], 
    'Both' => ['1000','2000'] 
} 

답변

1
  1. 필요 해시로 중복 제거하여
  2. 공통적이지 않은 모든 요소를 ​​찾습니다.

을 감안할 때 두 배열은 @x, @y,이 의미 :

use List::MoreUtils 'uniq'; 

# find all common elements 
my %common; 
$common{$_}++ for uniq(@x), uniq(@y); # count all elements 
$common{$_} == 2 or delete $common{$_} for keys %common; 

# remove entries from @x, @y that are common: 
@x = grep { not $common{$_} } @x; 
@y = grep { not $common{$_} } @y; 

# Put the common strings in an array: 
my @common = keys %common; 

지금 남아있는 그 모든 역 참조와 같은 약간의 작업을 수행하는 것입니다,하지만 그건 매우 사소한해야한다.

+0

@common의 출력은 유사하거나 유사하지 않더라도 @x 및 @y의 concat입니다. –

+0

@ PatrickRobertSheaO'Connor 죄송합니다. 지금 수정되었습니다. 각 요소의 배열 수를 계산 한 다음 배열 수가 배열 수 아래 인 요소를 제거해야합니다. – amon

0

다른 모듈이 필요 없습니다. perl 해시가 uniq 또는 일반적인 값을 찾는 데 실제로 유용합니다.

my %both; 
# count the number of times any element was seen in 4 and 6 
$both{$_}++ for (@{$VAR1->{4}}, @{$VAR1->{6}}); 
for (keys %both) { 
    # if the count is one the element isn't in both 4 and 6 
    delete $both{$_} if($both{$_} == 1); 
} 
$VAR1->{Both} = [keys %both];