루비가 쿨한 이유 3 - 해시

Posted by 大山 Sun, 06 Aug 2006 17:51:00 GMT

[참고: 이 글은 루비가 쿨한 이유 1 - irb, 루비가 쿨한 이유 2 - 블록에 이어지는 시리즈임.]

해시(Hash)는 Associative Array라고도 종종 불리는데 루비에서 가장 많이 쓰이는 데이타 구조 중 하나이다. 해시에는 키값과 데이타가 짝으로 저장되는데, 다음과 같은 식이다.

h = Hash.new
h["name"] = "홍길동"
h["age"] = 18
h["sex"] = "남자"
 

저장한 데이타를 불러오려면 원래의 키값만 알고 있으면 된다. 예를 들어, h["name"]은 "홍길동"을 리턴한다. h["address"]와 같이, 존재하지 않는 키값이 입력되면 nil이 리턴된다.

해시는 대부분의 프로그래밍 언어에서 지원되지만, 모든 프로그래밍 언어에서 같은 빈도로 활용되지는 않는다. 보통 Perl이나 루비 코드에는 해시가 넘쳐나는데 반해, 자바 코드에서는 해시를 찾아보기가 어렵다.

이런 현상은 프로그래밍 언어는 평등하지 않다는 것을 보여주는 또다른 예라고 할 수 있다. 자바의 해시는 HashMap 클래스의 API를 통해서만 사용이 가능하지만, 루비나 Perl은 언어의 신택스 레벨에서 해시를 지원하기 때문이다.

예를 들어, 자바에서 숫자와 요일을 매핑하는 해시를 만드려면 다음과 같은 코드가 필요하다.

import java.util.HashMap;

class HashExample {
  static void main(String[] argv) {
    HashMap h = new HashMap();
    h.add(new Integer(0), "일요일");
    h.add(new Integer(1), "월요일");
    h.add(new Integer(2), "화요일");
    h.add(new Integer(3), "수요일");
    h.add(new Integer(4), "목요일");
    h.add(new Integer(5), "금요일");
    h.add(new Integer(6), "토요일");
  }
}
 

루비에서는 다음과 같다.

h = {0 => "일요일", 1 => "월요일", 2 => "화요일",
     3 => "수요일", 4 => "목요일", 5 => "금요일",
     6 => "토요일"}
 

왜 자바 개발자들이 해시를 잘 안쓰는지는 읽는 분의 상상에 맡긴다. 해시가 유용한 경우는 정말로 많은데, 대표적인 예는 특정 이벤트가 일어난 횟수를 저장하기 위해서이다. 예를 들어, 웹 로그 파일에서 특정 IP 주소의 접속 빈도를 합산하는데 사용할 수 있다.

c:\> irb --simple-prompt
>> f = File.open("access_log", "r")
>> h = Hash.new(0)
>> f.each {|line| h[$1] += 1 if line =~ /^(\d+\.\d+\.\d+\.\d+)/}
 

위에서 Hash.new(0)이라고 한 것은, 해시에 아직 저장되지 않은 키값을 입력했을때 nil 대신에 0을 리턴하도록 해준다.

해시의 키값이나 데이타에는 어떤 객체도 들어갈 수 있기 때문에 또다른 해시 객체가 데이타로 들어갈 수도 있다. 예를 들어 다음과 같은 식이다.

h = {1 => {"name" => "이승만", "from" => 1948, "to" => 1960},
     2 => {"name" => "윤보선", "from" => 1960, "to" => 1962},
     3 => {"name" => "박정희", "from" => 1963, "to" => 1979},
     4 => {"name" => "최규하", "from" => 1979, "to" => 1980},
     5 => {"name" => "전두환", "from" => 1980, "to" => 1988},
     6 => {"name" => "노태우", "from" => 1988, "to" => 1993},
     7 => {"name" => "김영삼", "from" => 1993, "to" => 1998},
     8 => {"name" => "김대중", "from" => 1998, "to" => 2003},
     9 => {"name" => "노무현", "from" => 2003, "to" => 2008}}
 

대통령들의 재임 기간을 계산해 보는 것도 간단하다.

(1..9).each do |i|
  puts h[i]["name"] + ": " +
       (h[i]["to"] - h[i]["from"]).to_s + "년"
end

이승만: 12년
윤보선: 2년
박정희: 16년
최규하: 1년
전두환: 8년
노태우: 5년
김영삼: 5년
김대중: 5년
노무현: 5년
 

루비 설치는 이곳을 참고!

Posted in  | Tags ,  | 6 comments | no trackbacks