일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- php5
- memory
- perl one-liner
- 연산자
- Oracle RAC
- Linux
- grid
- cygwin
- prompt
- solaris
- 오라클
- perl + 정규표현식
- dba
- MySQL
- mariaDB
- bash
- rac
- Network
- perl string
- oracle install
- sqlplus
- solaris network
- RHEL4
- patch
- oracle
- command & perl
- SQL
- PERL
- fdisk
- Unix
- Today
- Total
DATA 전문가로 가는 길
[Perl] Hash(해쉬)란? 본문
스칼라 변수와 배열 그외에 어떤 변수가 있는지 아실 겁니다.
사실 저도 이번에 해쉬 문법을 배우면서 참 유용하게 쓰일 곳이 많을 거라고 생각 했습니다.
해쉬는 key + value값을 가지고 일종의 배열 역활을 합니다.
문자열을 첨자로서 값을 취득할 수 있는 배열이라고 생각해도 나쁘지 않다고 생각 합니다.
%(백분율 기호)를 사용 하여 배열을 선언 합니다.
my %hash = ( 'key' =>'values' ); |
- 변수의 접두사는 %
- (key1 => value1, key2 => value2 .... )
- 부모(key)와 자식(value)으로 비유하기도 합니다.
- 해쉬의 키값으로는 문자열이나 변수명이 올 수 있는데, 굳이 이중인용부호로 감싸지 않아도 됩니다. 그러나, 만일 키값이 2byte문자체계인 한글이 사용된다면 반드시 인용부호가 필요하다는 점 기억해야 합니다.
print "$hash{key} \n"; 결과 : values |
- 출력하는 경우, %가 아니라 $기호로 단일 요소를 취급해야 합니다.
- {}를 사용하여 키를 지정합니다. (배열은 []을 기준으로 하겠죠?)
이 정도면 해쉬를 어떻게 사용하는지 어떻게 출력 하는지 알 수 있을 거라고 생각 합니다. 그리고 중요한 건 연관 배열 관련 함수인데요. 이것은 해쉬로 들어있는 값을 print문으로 계속 하는 것은 맞지 않다고 생각 합니다. 연관 배열 내에서 다음 키/값을 쌍으로 두 개의 요소를 갖고 오는 방법도 있으니 방법은 다양 합니다.
keys(%ARRAY) | %ARRAY내의 모든 "key"의 목록을 리턴 (목록은 랜덤하며, 순서는 내부적으로 사용된 해쉬함수에 의존 |
values(%ARRAY) | %ARRAY내의 모든 "valus'의 목록을 리턴 |
each(%ARRAY) | %ARRAY로 함수가 호출 될 때마다 연관 배열 내의 다음 "key/value"를 쌍으로 구성하여 두개의 요소를 갖는 목록을 리턴 |
delete($ARRAY{KEY}) | %ARRAY로 부터 KEY와 연관된 "key/value"을 제거 |
1. keys 함수
use strict; use warnings; my %math_score = ( 'eng' => 58, 'mat' => 100, 'perl' => 120, ); my $sum; my $cnt; foreach my $key ( sort keys %math_score ) { print "$key : $math_score{$key} \n"; $sum += $math_score{$key}; $cnt++; } print"-----------------------\n"; print" RESULT \n"; print"-----------------------\n"; printf "SUM : %4d AVG : %0.2f \n",$sum, $sum / $cnt; print"-----------------------\n"; 결과 : eng : 58 mat : 100 perl : 120 ----------------------- RESULT ----------------------- SUM : 278 AVG : 92.67 ----------------------- |
설명
- keys 함수를 이용하여 해쉬의 각각의 요소들을 foreach에 건내 줍니다.
- print "$key : $math_score{$key} \n"; 이부분에서 위에서 설명했던 key를 이용하여 value를 출력
printf "SUM : %4d AVG : %0.2f \n",$sum, $sum / $cnt; 따로 설명이 .....
- 제가 프로그램을 만들면서 혼란 스러웠던건 스칼라변수를 어디에 써야하고 각 lexical scope(영역)을 구분하기가 어려웠습니다. 가장 간단한 방법은 { }를 기준으로 생각하시면 될 것 같습니다.
2. each 함수
use strict; use warnings; my %math_score = ( 'eng' => 58, 'mat' => 100, 'perl' => 120, ); my $sum; my $cnt; while ( (my $key, my $value) = each(%math_score) ) { print "$key = $value \n"; $sum += $value; $cnt++; } print"-----------------------\n"; print" RESULT \n"; print"-----------------------\n"; printf "SUM : %4d AVG : %0.2f \n", $sum, $sum / $cnt; print"-----------------------\n"; 결과 : perl = 120 mat = 100 eng = 58 ----------------------- RESULT ----------------------- SUM : 278 AVG : 92.67 ----------------------- |
- (my $key, my $value) = each(%math_score)
each 함수는 해쉬를 인수하여 키와 값을 스칼라 변수로 전달합니다.
- each 함수는 순서부를 정의 할 수 없으며, 사전 순서를 변경 하기 위해서는 keys함수를 사용
- each 함수는 메모리 소비량은 많지 않지만 keys 함수는 키의 모든 것을 메모리에 활당
3. delete 함수
#!/usr/bin/perl use strict; use warnings; my %math_score = ( 'eng' => 58, 'mat' => 100, 'perl' => 120, ); my $sum; my $cnt; my $key; my $value; delete($math_score{perl}); while ( ($key, $value) = each(%math_score) ) { print "$key = $value \n"; $sum += $value; $cnt++; } print"-----------------------\n"; print" RESULT \n"; print"-----------------------\n"; printf "SUM : %4d AVG : %0.2f \n", $sum, $sum / $cnt; print"-----------------------\n"; 결과 : mat = 100 eng = 58 ----------------------- RESULT ----------------------- SUM : 158 AVG : 79.00 ----------------------- |
- delete($math_score{perl}); 해쉬에 등록된 값을 삭제 하는 방법이며, "perl"이라는 key를 제거하게 되면 key/value 모두 제거 하게 됩니다. 그래서 실제로 결과를 보면 perl이라는 해쉬는 존재 하지 않습니다.
그외에 reverse 함수도 있습니다. 방법은 key/value를 서로 값을 바꿔 주는 함수라고 생각 하시면 됩니다.
예 : my %y = reverse %x ;
전체적인 해쉬를 설명할 수는 없습니다. 해쉬를 이용하여 래퍼런스 혹은 디래퍼런스를 활용 할 수도 있고
배열에 해쉬를 작성하여 래퍼런스 임시적 래퍼런스 값을 추려낼 수도 있습니다.
4. 응용 사례
결과 : ID : estenpark PW : ucess IP : 203.223.233.231 ID : m12 PW : ucess IP : 203.223.233.232 ID : mas12 PW : ucess IP : 203.223.233.233 ID : ma2345 PW : ucess IP : 203.223.233.234 |
위와 같은 방법은 배열에 해쉬를 이용하여 필요한 정보를 수집하는 자료구조입니다.
{ id=>'estenpark', pass=>'ucess', ip=>'203.223.233.231' },
..
..
배열에 원소는 4개가 되지만, 실제적으로 값을 해쉬 배열이 됩니다. 그것은 실제 주소를 불러오면 알 수 있습니다.
foreach my $ip ( @server_data ) { 출력 } 위에서 말한 것 처럼 배열에 있는 원소를 변수에 전달 하게 되면 그 값을 역 참조하여 값을 추려 낼 수 있습니다.
printf "ID : %10s PW : %10s IP : %16s \n", $ip->{id}, $ip->{pass}, $ip->{ip};
$ip ->{id} 각각의 원소 안에 해쉬의 key를 넣어 주면 value를 출력 하게 됩니다.
5. 적용 방법
#!/usr/bin/perl use strict; use warnings; my %server_data = ( '203.223.233.231'=> { id=>'estenpark', pass=>'ucess', }, '203.223.233.232'=> { id=>'mass' , pass=>'ucess', }, '203.223.233.233'=> { id=>'mas12' , pass=>'ucess', }, '203.223.233.234'=> { id=>'ma2345' , pass=>'ucess', } ); foreach my $ip ( keys %server_data ) { printf "ID : %10s PW : %10s IP : %16s \n", $server_data{$ip}->{id}, $server_data{$ip}->{pass}, $ip; } 결과 : ID : estenpark PW : ucess IP : 203.223.233.231 ID : mas12 PW : ucess IP : 203.223.233.233 ID : ma2345 PW : ucess IP : 203.223.233.234 ID : mass PW : ucess IP : 203.223.233.232 |
저도 해쉬 변수에 넣은 방법을 보고 어떻게 하면 출력 할까.. 정말 많은 고민을 했습니다. 만약 '203.223.233.231' 번의 아이피의 id를 알고 싶다면 어떻게 해야 할까요?? print "$server_data2{'203.223.233.231'}->{id} \n";
현재 소스에는 4개의 배열 밖에 없지만 실제로 서버가 100대 2000대 라면 그걸 모두 print문으로 하면 코딩도 길어지고 정말 쓸모 없는 작업을 하게 됩니다.
foreach my $ip ( keys %server_data ) { 출력 } 앞서 말한 것 처럼 해쉬 변수에 적용 되어있기 때문에 keys 함수를 이용해서 각 원소의 결과를 가지고 올 수 있었습니다.
정렬을 하고 싶다면 sort 를 적용 시켜서 사용 하셔도 됩니다.
foreach my $ip ( sort keys %server_data ) { 출력 } 이렇게 하면 정렬 되겠죠?
참고 자료
================================================================================
사이트 이름
================================================================================
http://aero.springnote.com/ (aero님)
http://h0ney.pe.kr/ (hOney님)
http://doc.perl.kr/twiki/bin/view/Wiki/HowToStartPerl (펄덕펄덕)
http://cafe.naver.com/perlstudy.cafe (대한민국Perl커뮤니티)
================================================================================
'Programming > Perl' 카테고리의 다른 글
[Perl] 서브루틴 (0) | 2009.04.07 |
---|---|
[Perl] Expect를 이용한 서버 체크하는 방법 (cygwin용) (2) | 2009.03.29 |
[Perl] 원라이너 디렉토리 안에 문자열을 찾아 각 월별 건수 확인 (4) | 2009.03.26 |
[Perl] Dereference 란? (2) | 2009.03.26 |
[Perl] 문법을 활용해서 1 부터 100까지 합 구하기 (3) | 2009.03.25 |