코드가 멀리 떨어져 있지 않습니다. 그것을 통해 가자.
oceans = ["Pacific; 1", "Atlantic; 2", "Indian; 3",
"Pacific; 2", "Atlantic; 1", "Pacific; 3"]
오히려 파일의 라인을 읽는 것보다. 코드가 작동하면 파일에서 읽기 쉽게 변경할 수 있습니다. 이제 우리는 어떤 입력 데이터를 가지고
, 우리는 우리가 예상 한 결과이 원하는 것을 보여줄 수 있습니다
hash =
{ 'Pacific' => ['1', '2', '3'],
'Atlantic' => ['2', '1'],
'Indian' => ['1'] }
또는
hash =
{ 'Pacific' => "'1', '2', '3'",
'Atlantic' => "'2', '1'",
'Indian' => "'1'" }
는 가장 쉬운 방법으로 우리는 첫 번째를 사용합니다 우리가 두 번째 형식을 원하면 처음부터 쉽게 계산할 수 있습니다.
hash.keys.each { |k| hash[k] = hash[k].join(',') }
#=> ["Pacific", "Atlantic", "Indian"]
그러나 기다림, tha t는 반환 된 해시가 아닙니다. 아니요, hash.keys
입니다. 이외에도
hash #=> {"Pacific"=>"1,2,3", "Atlantic"=>"2,1", "Indian"=>"1"}
: 우리가 원하는 것은 hash
의 새로운 값 질문을 게시하는 경우에 따라서는 예상 된 결과와 함께 약간의 설명을 입력 데이터를 포함하는 것이 도움이됩니다. 그것은 명확하고 단어를 저장하는 경향이 있습니다. 가능한 한 적은 데이터로 사용해보십시오.
코드는
다음 코드는 파일의 읽기 대체 배열 oceans
로,이다는 :
descriptor_code_hash[mesh_descriptor] = tree_code
각 :
descriptor_code_hash = Hash.new
oceans.each do |file_line|
file_line = file_line.chomp
mesh_descriptor, tree_code = file_line.split(/\;/)
descriptor_code_hash[mesh_descriptor] = tree_code
if descriptor_code_hash.has_key? mesh_descriptor
tree_code << "," << tree_code
else
descriptor_code_hash[mesh_descriptor]
end
end
가장 큰 문제는 라인 루프를 통과 할 때 mesh_descriptor
의 descriptor_code_hash
값이 res입니다. 현재 (파일의 행을 나타냄)의 요소에 대해 tree_code
의 값으로 변경합니다. 이 행을 삭제해야합니다. 우리가 이것을 실행하면
descriptor_code_hash = Hash.new
oceans.each do |file_line|
file_line = file_line.chomp
mesh_descriptor, tree_code = file_line.split(/\;/)
if descriptor_code_hash.has_key? mesh_descriptor
descriptor_code_hash[mesh_descriptor] << tree_code
else
descriptor_code_hash[mesh_descriptor] = [tree_code]
end
end
, 우리가 얻을 :
descriptor_code_hash
#=> {"Pacific"=>[" 1", " 2", " 3"], "Atlantic"=>[" 2", " 1"],
# "Indian"=>[" 3"]}
if descriptor_code_hash.has_key? mesh_descriptor
descriptor_code_hash[mesh_descriptor] << tree_code
else
descriptor_code_hash[mesh_descriptor] = [tree_code]
end
이 다음 당신에게 제공 : 다음과 같이
다음으로, 우리는 당신의 if/else/end
문을 변경해야
작은 포맷 문제가 있다는 것을 제외하면 결과가 정확합니다. 우리는 변화에 의해 그 문제를 해결할 수 있습니다 :
file_line.split(/\;/)
두 가지 방법으로 간단하게 할 수있는
file_line.split(/\;/).map { |w| w.strip }
에 : file_line.split(';').map(&:strip)
것은 그것을 시도하자. 한다고 가정
file_line = "Pacific; 1\n"
그럼
file_line.split(';').map(&:strip) #=> ["Pacific", "1"]
원하는 결과이다. 문자열 끝에 줄 바꿈 문자가 포함되어 있음을 주목하십시오. 그것은 strip
이 공백뿐만 아니라 그것을 제거한다는 것을 보여줍니다. 즉, 이전 줄 필요가 없습니다 의미 : (. file_line.chomp.split(/\s*;\s*/)
도 작동)
이 file_line = file_line.chomp
을
귀하의 코드는 지금까지 간체된다
descriptor_code_hash = Hash.new
oceans.each do |file_line|
mesh_descriptor, tree_code = file_line.split(';').map(&:strip)
if descriptor_code_hash.has_key? mesh_descriptor
descriptor_code_hash[mesh_descriptor] << tree_code
else
descriptor_code_hash[mesh_descriptor] = [tree_code]
end
end
이
연마 이제 루비와 같은 코드를 만들기 위해 할 수있는 일을 생각해보십시오. 첫째, (당신의 if/else/end
구조 대신에) @BroiSatse에 의해 주어진 답에 사용 된 다음 줄에 보면 : 어떤 변수 a
를 들어
(descriptor_code_hash[mesh_descriptor] ||= []) << tree_code
이 a ||= []
가 a = (a || [])
과 동일합니다.a
이 정의되어 있지 않으면 nil
과 같으므로 (nil || []) => []
이됩니다. a
에 (0이 아닌) 값이 지정되면 (a || []) => a
. 즉, descriptor_code_hash
에 mesh_descriptor
(의미 : descriptor_code_hash[mesh_descriptor] => nil
) 키가없는 경우 descriptor_code_hash[mesh_descriptor]
에 []
이 할당됩니다. 그렇지 않으면 자체적으로 할당됩니다 (즉 변경되지 않음).
descriptor_code_hash[mesh_descriptor] ||= []
실행
후 descriptor_code_hash[mesh_descriptor]
빈 또는 다른 배열을 같게한다. << tree_code
다음 해시 값 (배열)에 tree_code
을 추가합니다. 마지막으로 대신 {}
을 사용할 수 있지만 그만의 문체가 있습니다.
귀하의 코드는 이제 다음과 같습니다
descriptor_code_hash = {}
oceans.each do |file_line|
mesh_descriptor, tree_code = file_line.split(';').map(&:strip)
(descriptor_code_hash[mesh_descriptor] ||= []) << tree_code
end
의 지금이 방법을 만들어 보자하고 몇 가지 더 변경합니다, 나는 변수 이름의 일부를 단순화했습니다
def descriptor_code_hash(oceans)
oceans.each_with_object({}) do |line, hash|
mesh_descriptor, tree_code = line.split(';').map(&:strip)
(hash[mesh_descriptor] ||= []) << tree_code
end
end
descriptor_code_hash(oceans)
#=> {"Pacific"=>["1", "2", "3"], "Atlantic"=>["2", "1"], "Indian"=>["3"]}
을하기 때문에 메소드의 목적은 이름으로 설명됩니다. 사용 방법을 보려면 Enumerable#each_with_object (버전 1.9부터 사용 가능)에 대한 문서를 읽어보십시오.
아마 메소드 인수로 파일 이름을 원할 것입니다.
마지막으로 한가지 :
여기 def descriptor_code_hash(oceans)
oceans.each_with_object(Hash.new {|k,h| h[k] = {} }) do |line, hash|
mesh_descriptor, tree_code = line.split(';').map(&:strip)
hash[mesh_descriptor] << tree_code
end
end
객체가 초기화되는 : 다음과 같이 당신이 대신 쓸 수있는 새 키를 추가 할 때의 기본값 (수
Hash.new {|k,h| h[k] = {} }
해시에) 빈 해시. 3 번째 줄부터 마지막 줄까지 그림과 같이 단순화 할 수 있습니다.
코드의 배열 대신 코드가 쉼표로 구분되기를 원하는 이유가 있습니까? – BroiSatse
관련 코드를 식별하기 위해 파일의 특정 용어에서 각 코드를 사용해야합니다. 문자열을 분리하고 각 코드를 쉽게 얻을 수 있다고 생각했습니다. 나는 각각의 값이 값의 배열 인 해시를 사용한 적이 없다. 당신이 그 전략에 익숙하다면 당신의 아이디어를 환영 할 것입니다! – user3385593
당신이 "다른 대답을 읽었지만" "내 질문에는 아무도 대답하지 못했다"라고 말하면 이미 시도한 ***에 대한 답변을 알려주는 데 도움이됩니다. **), 그래서 우리는 똑같은 대답을 반복하지 않게됩니다. 왜냐하면 그것은 단지 *** 모든 사람의 시간, 우리와 당신의 시간을 낭비하기 때문입니다. –