2011-11-10 15 views
15

표준 루비 구조체의 데이터를 해시 (멤버, 값 쌍)로 반환 할 수있는 유효한 이유가 있습니까? 구조체와 해시가 매우 유사한 사용 사례를 가지고있는 것을 보면, 나는 그런 메서드가 존재하지 않는다는 것에 놀랐습니다. 아니면 그렇게하고, 나는 너무 맹인인가?구조체 데이터를 루비의 해시로 반환

구현하기 쉽습니다 (그리고 지금까지 했었습니다). 그러나 표준 라이브러리에서 그러한 기능이 부족하여 루비에서 구조체의 개념을 정말로 이해하지 못했을 것이라고 생각합니다.

답변

30

(루비 < = 1.9.3) OpenStructOpenStruct#marshall_dump이고 StructStruct#each_pair입니다 (해시를 얻으려면 to_a을 사용하고 Hash + to_a 해시를 얻으세요) :

루비와
Person = Struct.new(:name, :age) 
person = Person.new("Jamie", 23) 
person_hash = Hash[person.each_pair.to_a] 
#=> {:age=>23, :name=>"Jamie"} 

2.0 일을 더 쉽게 위치 : Struct#to_h, OpenStruct#to_h :

Person = Struct.new(:name, :age) 
person = Person.new("Jamie", 23) 
person_hash = person.to_h 
#=> {:age=>23, :name=>"Jamie"} 
+0

이 'injectless'솔루션에 대해 고맙습니다. 그리고 더 중요한 것은 informatian에 대해 OpenStruct에는 그런 방법이 있습니다. 이것은 Ruby Struct (궁극적으로는 그것입니다)에 대해 물어볼 수있는 가능한 일입니다. – cvshepherd

+4

Ruby 2.0에는 Struct에 to_h 메소드가 있습니다. –

4

해시 및 구조체의 사용 사례가 매우 유사하다고 생각하지 않습니다. 해시를 사용하면 다양한 수의 키 - 값 쌍을 저장할 수 있으며 원하는 경우 수천 개의 쌍을 저장하는 데 적합합니다. 특별한 키는 존재하지 않습니다. 구조체를 사용하면 항상 "키"집합이 무엇인지 알 수 있으며 대개 작습니다 (20 미만).

해시는 정보의 일부를 많은 수의 다른 개체와 연관시키는 데 사용할 수 있습니다. 해시는 함수에 선택적 매개 변수를 지정하는 데 사용됩니다. 구조체는 잘 정의 된 정보를 하나의 객체에 보관하려는 경우에 사용할 수 있습니다.

구조체를 해시로 변환하지 않으려 고 한 이유가 궁금합니다.

수정 1 : 구조체와 함께 해쉬하지 않는 구문을 사용할 수 있다는 것을 알고 계셨습니까?

P = Struct.new(:x,:y) 
p = P.new(1,2) 
p.x # => x 

편집 2 : 해시가 빠르게 개체를 검색 할 수 있습니다. obj_hashed_by_name[name]obj_array.find { |a| a.name == name }보다 훨씬 빠릅니다.

+1

난 아직도 이유를 들어 볼 사용 구성원, 값 쌍을 해시로 검색 할 수 없습니다. 특히 구조체가 전혀 문제가되지 않는다는 것을 고려하면 배열처럼 작동합니다. 때때로 깔끔한 방식으로 찾을 수 있지만 컨텍스트가없는 구조체 (멤버)의 값을 얻는 것은 거의 쓸모없는 것처럼 보입니다. – cvshepherd

2

난 당신이 중 하나 그것을 할 싶어 왜 모르는 것 같아요,하지만 : each_with_object 사용

s.members.inject({}) { |m, f| m[f] = s[f]; m } 

또는 :

s.members.each_with_object({}) { |m, h| h[m] = s[m] } 
+0

내가 필요로하는 이유/이것을 원한다면, 해시 값을 기준으로 정렬 할 수 있어야합니다. – cvshepherd

+1

@cvshepherd Ah.나는 클래스를 사용했을 것이라고 생각하지만, 지금은 알게 될 것이다. :) –

0

허용 된 대답은 나를 위해 작동하지 않았다, 나는 대신 다음

require 'ostruct' 
require 'date' 

lid = OpenStruct.new(:status=>0,:rowversion=>0,:cre_dt=>DateTime.now.to_date,:cre_user=>'9999999') 
p Hash[lid.each_pair.to_a] #=> {} 
p lid.marshal_dump #=>{:status=>0, :rowversion=>0, :cre_dt=>#<Date: 2014-03-03 ((2456720j,0s,0n),+0s,2299161j)>, :cre_user=>"9999999"} 
관련 문제