2009-06-11 3 views

답변

11

Ruby 1.9에서 는 정렬되지만 은 여전히 ​​ArrayArray으로 반환합니다. 상상 해봐! 그것은 당신이 그것의 위에 자신의 정렬 방법을 만들 수 있다는 것을 암시한다.

class Hash 
    def sorted_hash(&block) 
    self.class[sort(&block)] # Hash[ [[key1, value1], [key2, value2]] ] 
    end 
end 

Hash Ruby 1.8에서는 분류되지 않았습니다. Ruby 1.8과의 호환성을 원하면 ActiveSupport의 OrderedHash을 사용할 수 있습니다. 그것은 1.9 Hash처럼 작동, 그래서 당신은 그것을 같은 sorted_hash 방법을 정의 할 수 있습니다

class ActiveSupport::OrderedHash 
    def sorted_hash(&block) 
    self.class[sort(&block)] 
    end 
end 

hash = ActiveSupport::OrderedHash.new 
hash["b"] = "b" 
hash["a"] = "a" 
hash    #=> {"b"=>"b", "a"=>"a"} => unsorted 
hash.sorted_hash #=> {"a"=>"a", "b"=>"b"} => sorted! 

가 기본적으로 존재하지 않기 때문에 당신은 당신의 코드에 sorted_hash 방법을 복사 할 수 있습니다! 깊은 분류에 대한

업데이트 : 당신이 해시 키가 아닌 다른 무언가에 정렬을 찾고 있다면 (위에서 구현을 가정)는 다음과 같이이 의 sorted_hash 방법으로 블록을 전달합니다

hash = ActiveSupport::OrderedHash.new 
hash["a"] = { "attr" => "2", "..." => "..." } 
hash["b"] = { "attr" => "1", "..." => "..." } 

# Unsorted. 
hash 
    #=> {"a"=>{"attr"=>"2", "..."=>"..."}, "b"=>{"attr"=>"1", "..."=>"..."}} 

# Sort on the "attr" key. (Assuming every value is a Hash itself!) 
hash.sorted_hash { |a, b| a[1]["attr"] <=> b[1]["attr"] } 
    #=> {"b"=>{"attr"=>"1", "..."=>"..."}, "a"=>{"attr"=>"2", "..."=>"..."}} 
+0

나는 당신을 얻지 못했습니다. 레일 2.3.2의 OrderedHash 소스 코드를 살펴본 결과, 정렬 방법과 관련하여 아무 것도 볼 수 없었습니다. – Dharam

+0

@satynos : 나는 그것을 조금 명확하게 설명했다. sorted_hash를 직접 정의해야하지만 정말 쉽습니다! 원한다면 구현을 복사하십시오. – molf

+0

@molf : excellent ... 구현에 대한 피드백과 도움에 감사드립니다. 또한 해시 클래스에서 메서드를 구현하면 작동합니까? 또는 ActiveSupport :: OrderedHash에 구현해야합니까? – Dharam

8

해시는 근본적으로 정렬되지 않은 데이터 구조입니다. Hash#sort은 실제로 원하는 것입니다. 어느 쪽이든, 또는 키 목록을 정렬 한 다음 해시를 직접 출력하는 대신 자체 메서드를 사용하여 해시를 출력 할 때이를 열거합니다.

+3

기술적으로 해시는 Ruby 1.9에서 주문됩니다. 그러나 재정렬에 대한 지원이 존재하지 않기 때문에 그들이 그렇지 않은 것처럼 대우하는 것이 여전히 일반적으로 더 바람직하다고 생각합니다. – Chuck

+0

짐, 예를 들어 주시겠습니까? – Dharam

+0

"기술적으로, 해시는 루비 1.9에서 주문됩니다."이것은 나를 매우 슬프게 만듭니다. 해시는 함축적 인 순서를 가져서는 안됩니다! 물론, 나는 때로는 주문을 원한다는 것을 이해하지만 그 데이터 구조에 대해 다른 이름을 만든다! Grr. – Beska