2014-09-08 7 views
1

문자열을 해시로 변환하는 더 좋은 방법이 있는지 궁금합니다. 내 문자열은 구조와 관련해서는 항상 똑같을 것입니다. 다음은 예입니다문자열을 해시로 변환

string = "range:12\ntype:default\n" 

@settings = Hash[ 
    *string.downcase 
    .split("\n") 
    .map{|s| [s.split(":")[0].to_sym, s.split(":")[1]]} 
    .flatten 
] 

p @settings 
# => {:range=>"12", :type=>"default"} 

이는 어떻게해야 않으며, 나는이 아무 문제가 없다. 하지만 극도로 읽을 수 없으며 코드에 대한 리팩토링 옵션이 있기를 바랍니다.

+0

왜 값 앞에 공백을 추가하지 않으며 YAML 그것을 만들어? –

답변

4

당신은 문자열의 키 - 값 쌍을 검색하고 단순히 to_h를 호출하여 해시 배열의 결과 배열을 변환 String.scan를 사용할 수 있습니다

string.scan(/(.+):(.+)\n/).to_h 
#=> {"range"=>"12", "type"=>"default"} 

당신이 정말로 기호 키를해야하는 경우 해시로 변환하기 전에 Array#map를 사용할 수 있습니다

string.scan(/(.+):(.+)\n/).map {|k,v| [k.to_sym, v]}.to_h 
#=> {:range=>"12", :type=>"default"} 

당신이 레일을 사용하는 경우, 이미 방법 Hash#symbolize_keys 내장있다 :

string.scan(/(.+):(.+)\n/).to_h.symbolize_keys 
#=> {:range=>"12", :type=>"default"} 
+0

좋은 예 ... 1+ –

+0

이것은 완벽합니다. 감사합니다. – Eugen

1

Hash::[] 배열의 배열을 처리 할 수 ​​

@settings = Hash[ 
    string.split("\n") 
    .map { |s| s = s.split(":"); [s[0].to_sym, s[1]] } 
] 
2

당신이 당신의 가치 이전에 공간이 있다면 :

string = "range: 12\ntype: default\n" 

이 문자열이 될 올바른 YAML을, 당신 때문에

require 'yaml' 
string = "range: 12\ntype: default\n" 
@settings = YAML.load(string) 
# => {"range"=>12, "type"=>"default"} 

그래서 : 루비와 yaml 라이브러리를 구문 분석 할 수 할 수 있으면 설정 형식을 약간 수정하는 것이 좋습니다.

+0

모든 답변 중에서, 이것은 텍스트 파일에 키 - 값 쌍을 저장하는 더 큰 문제에 대해 가장 강력한 방법입니다. 나는 이런 식으로 질문을 뒤돌아 보는 것이 좋고 훌륭한 대답의 차이를 만든다고 생각합니다. +1 –

+0

이것은 정말 좋지만 yaml을 사용할 수 없습니다. – Eugen

2

이 작동합니다 :

string = "range:12\ntype:default\n" 

string.split("\n").each_with_object({}) { |s, h| 
    k, v = s.split(':') 
    h[k.to_sym] = v 
} 
#=> {:range=>"12", :type=>"default"} 
5
Hash[*string.split(/[:\n]/)] 
# => {"range"=>"12", "type"=>"default"} 
관련 문제