2011-12-07 3 views
2

하나의 해시가 다른 해시의 하위 집합인지 비교하기 쉬운 알고리즘이 있는지 궁금합니다. 예를 들어perl, 해시 비교, 서브 세트

,

$HASH{A} = B; 
$HASH{B} = C; 
$HASH{C} = D; 

$HASH2{A} = B; 
$HASH2{B} = C; 

다음 HASH2 %의 %는 해시의 서브 세트 인 경우.

+0

하셨습니까'$ HASH2'대신'$ HASH1 {A}'의 {A}? –

+0

@MattFenwick : 아마도 - 나는 계속 나아갔습니다. 고든, 내가 틀렸다고해도 제 편집 내용을 되 돌리십시오. – derobert

+0

수정 해 주셔서 감사합니다! – Gordon

답변

1

가정 당신의 해시가 간단한 루프와 함께이 작업을 수행 할 수 있습니다 (예를 들어, 그들은 값으로 참조를 포함하지 않는) 간단합니다 : 영어

sub is_subset { 
    my ($h1, $h2) = @_; 

    while (my ($k, $v) = each %$h1) { 
     exists $h2->{$k} && $v eq $h2->{$k} 
      or return; # in case of list context, thanks davorg 
    } 
    return 1; 
} 

, 즉, 각 키 값 쌍 통과 첫 번째 해시를 요청하고 (a) 두 번째 해시의 키이고 (b) 그렇다면 값이 같은지 묻습니다. 그렇지 않다면 첫 번째 해시는 두 번째 해시의 하위 집합이 아닙니다. 그렇지 않으면 그렇습니다.

당신의 해시가 예를 들어, 더 복잡한 경우, 값은하는 hashref 수 있습니다 다음 CPAN을 더 나은 (예, { h2 => { a => 1 } }의 부분 집합 { a => 1 }입니다) '집합'을 정의하고, 아마 재귀를 사용 (또는 확인하는 첫번째 필요).

+0

니스! 숫자에 대해서도 효과가 있습니까? –

+0

@MattFenwick : 값이 숫자라는 것을 알고 있다면,'eq'를'=='로 바꿀 것입니다. – derobert

+0

@MattFenwick 스마트 매치 연산자는 문자열이나 정수에 대해 작동합니다. '$ a ~~ $ b' – Axeman

4

"smart matching" (~~) 및 사용 List::Util::first

use 5.010; 
use List::Util qw<first>; 

sub hash_is_subset { 
    my ($hash, $cand) = @_; 
    return not defined(first { not $hash->{ $_ } ~~ $cand->{ $_ } } keys %$cand); 
} 

hash_is_subset(\%HASH, \%HASH2); 
+0

전에 스마트 매치를 들어 본 적이 없습니다. 머리를 주셔서 감사합니다! –

+0

스마트 매치는 놀라움을 가져올 수 있습니다. 예 :'{a => "hello"}''{a => qr /./} '의 하위 집합입니까? 똑똑한 성냥은 예라고 말합니다, 나는 꽤 확신합니다. – derobert