2013-08-23 3 views
1

펄 전문가를위한 쉬운 ...펄 해시 문제

단순히의 주요 섹션에서 각 항목을 횟수를 항목 (실제로 여러 배열)의 배열로 받아 계산 기능을 원하는 해시가있다. 그러나 Perl 해시를 확실히 알지 못합니다.

my %hash = (
    'banana' => 0, 
    'orange' => 0, 
    'apple' => 0 
    #I intentionally left out pear... I only want the values in the array... 
); 

그러나, 나는 그 통해 갈 수있는 일을하고 해당과 값에 1을 추가하는 루프를 받고 고군분투 :

@array = qw/banana apple orange apple orange apple pear/ 

난 당신이 같은 코드를 사용하여 배열을 할 필요가 읽어 보시기 바랍니다 키는 배열의 각 항목에 대한 배열의 값과 같습니다.

foreach $fruit (@array) { 
    if ($_ #is equal to a key in the hash) { 
     #Add one to the corresponding value 
    } 
} 

이 몇 가지 기본적인 기능을 모두 시작 펄 프로그래머를 대신하여, 사전에 감사합니다, 그래서 모든 일에 싸서있다!

답변

1

exists을 사용할 수 있습니다. 해시의 요소를 지정하는식이 주어

http://perldoc.perl.org/functions/exists.html

가 참을 반환 해시 지정된 요소가 어느 초기화 된 경우에도 해당 값은 정의되지 않은 경우.

foreach my $fruit (@array) { 
    if (exists $hash{$fruit}) { 
     $hash{$fruit}++; 
    } 
} 
+4

해시 요소가 있는지 여부를 확인할 필요가 없습니다. 게다가, 시작으로 요소의 * none *이 존재하기 때문에 프로그램은 결코 해시를 수정하지 않습니다. – Borodin

+0

제 잘못입니다. 나는 그가 정의한 해시의 값을 증가시키고 싶다는 인상하에 있었다. – Nate

+0

아, 알겠습니다. 나는 생각한다. 당신은 해쉬에 정의 된 바와 같이, OP가 카운트 된 단어의 서브 세트만을 원한다고 가정하고 있었습니까? 이 경우 코드가 정상입니다. – Borodin

6

당신이 필요로하는 모든이가

my %counts = (apple => 3, banana => 1, orange => 2, pear => 1) 

for 루프 블록을 기록 할 수 있으며, 명시 적 루프 카운터 변수 당신이 만약 같은 해시 결과

my @array = qw/banana apple orange apple orange apple pear/; 
my %counts; 
++$counts{$_} for @array; 

입니다 좋아, 이렇게하면

for my $word (@array) { 
    ++$counts{$word}; 
} 

정확히 동일한 효과.

+0

여러 배열에 대해이 기능을 확장 할 수있는 방법이 있습니까? – Padawan

+0

@ J.A. : 당신이 무슨 뜻인지 명확하지 않습니다. 여러개의 배열에 개수를 쌓고 싶다면 @ array1, @ array2, @ array3에 ++ $ counts {$ _}를 쓸 수있다. – Borodin

1

@array이라는 배열이 있다고 가정합니다. $array[0]을 사용하여 배열의 0 번째 요소에 액세스합니다.

해시는 유사합니다. %hash의 바나나 요소는 $hash{'banana'}으로 액세스 할 수 있습니다.

아주 간단한 예입니다. if (exists $hash{'banana'}) {...}가 : 필요한 경우 특정 해시 키가있는 경우

use strict; 

my @array = qw/banana apple orange apple orange apple pear/; 

my %hash; 
$hash{$_} += 1 for @array;    #add one for each fruit in the list 
print "$_: $hash{$_}\n" for keys %hash; #print our results 

, 당신은 확인할 수 있습니다 : 그것은 암시 적 변수 $_ 및 문자열 보간의 약간을 사용합니다.

해시가 아닌 의 해시를 참조하는 'hashref'라는 것을 보게 될 것입니다. 이 경우 $hashref$hashref->{'banana'}입니다.

1

나는 당신을 이해하려고 노력 해요 :

  1. 당신은 배열과 해시가 있습니다.
  2. 배열의 항목 수를 계산하고 발생 시간을 확인하려는 경우
  3. 이 항목이 해시에있는 경우에만 해당합니다.

해시는 키가 개라고 생각합니다. 배열에는 위치가 있습니다. 0 번째 요소 또는 5 번째 요소에 대해 이야기 할 수 있습니다. 오직 하나의 0 번째 요소가 있고 그것들은 오직 하나의 5 번째 요소입니다. 해시에서

살펴 보자 : 우리는 0 번째 위치에 배열의 요소에 대해 이야기 할 수있는 것처럼

my %jobs; 
$jobs{bob} = "banker"; 
$jobs{sue} = "banker"; 
$jobs{joe} = "plumber; 

, 우리는 bob의를 가진 요소에 대해 이야기 할 수 있습니다. 0 번째 위치에 하나의 요소가있는 것과 마찬가지로 bob 키가있는 요소는 하나만있을 수 있습니다.

해시는 정보를 빠르게 검색 할 수있는 방법을 제공합니다. 예를 들어, 내가 빨리 고소의 직업을 찾을 수 있습니다

print "Sue is a $jobs{sue}\n"; 

을 우리는 가지고 :

  • 항목 가득 배열입니다.
  • 계산하려는 항목이있는 해시
  • 합계가있는 다른 해시입니다. 전체리스트를

    use strict; 
    use warnings; 
    use feature qw(say); 
    
    my @items  = qw(.....); # Items we want to count 
    my %valid_items = (....); # The valid items we want 
    
    # Initializing the totals. Explained below... 
    my %totals; 
    map { $totals{$_} = 0; } keys %valid_items; 
    
    for my $item (@items) { 
        if (exists $valid_items{$item}) { 
         $totals{$item} += 1; #Add one to the total number of items 
        } 
    } 
    
    # 
    # Now print the totals 
    # 
    for my $item (sort keys %totals) { 
        printf "%-10.10s %4d\n", $item, $totals{$item}; 
    } 
    

    map 명령 (우리의 경우 keys %valid_items에서) 우측 항목의 리스트를 취하고, 루프 :

여기서 코드이다.

따라서 :

map { $totals{$_} = 0; } keys %valid_items; 

가 말하는 짧은 방법입니다

에 대한

(키 % valid_items) { $ 합계 {$ _} = 0; }

내가 사용하는 다른 것은 keys입니다. 이는 내 해시의 모든 키를 배열 (정상 목록)으로 반환합니다. 따라서 내가 keys %valid_items이라고 말하면 apple, bananaoranges이됩니다.

[exists](http://perldoc.perl.org/functions/exists.html) is a test to see if a particular key is in my hash. The value of that key might be zero, a null string, or even an undefined value, but if the key is in my hash, the exists 함수는 true 값을 반환합니다.

그러나 exists을 사용하여 키가 내 %valid_items 해시에 있는지 확인할 수있는 경우 %totals과 동일하게 처리 할 수 ​​있습니다. 그들은 같은 열쇠 세트를 가지고 있습니다.

해시 대신 %valid_items 해시를 만들려면 배열이 해시보다 초기화하기가 쉽기 때문에 @valid_items 배열을 사용합니다. 값을 나열하면됩니다. 대신 키의 목록을 얻을 수 keys %valid_items를 사용하여, 나는 @valid_items를 사용할 수 있습니다

use strict; 
use warnings; 
use feature qw(say); 

my @items = qw(banana apple orange apple orange apple pear); # Items we want to count 
my @valid_items = qw(banana apple orange); # The valid items we want 

my %totals; 
map { $totals{$_} = 0; } @valid_items; 

# Now %totals is storing our totals and is the list of valid items 

for my $item (@items) { 
    if (exists $totals{$item}) { 
     $totals{$item} += 1; #Add one to the total number of items 
    } 
} 

# 
# Now print the totals 
# 
for my $item (sort keys %totals) { 
    printf "%-10.10s %4d\n", $item, $totals{$item}; 
} 

그리고 이것은 출력한다 : 나는 printf 사용하여 좋아

apple   3 
banana   1 
orange   2 

을 테이블이 좋은 질서 유지를 위해.

1

2 개월 전으로 코드를 작성하기 시작 했으므로 이해하기 쉽습니다.

use Data::Dumper; 
use strict; 
use warnings; 
my @array = qw/banana apple orange apple orange apple pear/; 

my %hashvar; 
foreach my $element (@array) { 
    #Check whether the element is already added into hash ; if yes increment; else add. 
    if (defined $hashvar{$element}) { 
     $hashvar{$element}++; 
    } 
    else { 
     $hashvar{$element} = 1; 

    } 

} 
print Dumper(\%hashvar); 

는 $ VAR1으로 출력에서 ​​= { '바나나'=> 1, '사과'=> 3, '오렌지'=> 2, '배'=> 1 를 인쇄합니다 }; 건배

+0

먼저 정의되어 있는지 검사 할 필요가 없다. 그냥'$ hashvar {$ element} ++'라고 말하면된다. 전에 존재하지 않았다면, 현재 존재할 것이고 값은 1입니다. –