2017-02-03 17 views
0

Я пишу программу, которая принимает входные данные, сохраняет ее как хэш и сортирует значения.Проблема с добавлением хэш-значения ruby ​​

У меня возникли проблемы с сопоставлением текущего значения хеша с переменной.

Пример ввода:
А 1
В 3
С 5
А 2
B 7
С 2

Образец Выход:

А 1 2
B 3 7
C 2 5

Все работает отдельно от этой части, и я не уверен, почему.

if values.key?(:keys) 
     if values[keys] >= val 
       values.store(keys,val.prepend(val + " ")) 
     else 
       values.store(keys,val.concat(" " + val)) 
     end 
     else 
     values.store(keys,val) 
    end 
     i = i + 1 
    end 

Остальной код:

#get amount of records 
size = gets.chomp 
puts size 
size = size.to_i 
values = Hash.new(0) 
i = 0 
while i < (size * 2) 
    text = gets.chomp 
#split string and remove space 
    keys = text.split[0] 
    val = text.split[1] 

#check if key already exists, 
# if current value is greater than new value append new value to end 
# else put at beginning of current value 

    if values.key?(:keys) 
    if values[keys] >= val 
      values.store(keys,val.prepend(val + " ")) 
    else 
      values.store(keys,val.concat(" " + val)) 
    end 
    else 
    values.store(keys,val) 
end 
    i = i + 1 
end 

#sort hash by key 
values = values.sort_by { |key, value| key} 
#output hash values 
values.each{|key, value| 
    puts "#{key}:#{value}" 
} 

Может кто-нибудь помочь мне? Это было бы очень признательно.

ответ

1

Короткий ответ: в вашем коде есть две ошибки. Вот фиксированная версия:

if values.key?(keys) 
    if values[keys] >= val 
    values.store(keys,values[keys].prepend(val + " ")) 
    else 
    values.store(keys,values[keys].concat(" " + val)) 
    end 
else 
    values.store(keys,val) 
end 
  • if заявления всегда оценки, как false, потому что вы искали хэш-ключ с именем :keys (который является Symbol), а не переменным вы объявили имени keys.
  • Даже с исправленной была обнаружена вторая скрытая ошибка: вы сохраняли неверное новое значение хэш-функции. val.concat(" " + val) даст вам результаты как A 2 2, а не A 1 2, так как он использует новое значение дважды, а не оригинальное значение.

С учетом сказанного, вы код по-прежнему очень запутанным читать ... Ваши переменные size, i, text, val, values, key и keys. Было бы намного проще понять, с более четкими именами переменных, если ничего другого :)

Здесь пока немного улучшенная версия, не изменяя общую структуру кода:

puts "How may variables to loop through?" 
result_length = gets.chomp.to_i 
result = {} 

puts "Enter #{result_length * 2} key-value pairs:" 
(result_length * 2).times do 
    input = gets.chomp 
    input_key = input.split[0] 
    input_value = input.split[1] 

    #check if key already exists, 
    # if current value is greater than new value append new value to end 
    # else put at beginning of current value 

    if result.key?(input_key) 
    if result[input_key] >= input_value 
     result[input_key] = "#{input_value} #{result[input_key]}" 
    else 
     result[input_key] = "#{result[input_key]} #{input_value}" 
    end 
    else 
    result[input_key] = input_value 
    end 
end 

#sort hash by key 
result.sort.to_h 

#output hash result 
result.each{|key, value| 
    puts "#{key}:#{value}" 
} 
+0

большое спасибо за вашу помощь! Я почесываю голову на это целую вечность haha ​​ – pugs

+1

Если вы хотите улучшить это дальше, то гораздо более разумная структура данных будет примерно такой: '{" A "=> [1, 2]," B " => [3, 7], "C" => [5, 2]} '. Затем вы можете выполнять любое переупорядочение ключей, не вмешиваясь в строковые манипуляции.(Например, ваша текущая версия будет разбита на входы '> = 10', или если вы назначите 3 или более значений для ключа.) –

0

Это было бы более Руби-иш способ написать код:

input = "A 1 
B 3 
C 5 
A 2 
B 7 
C 2" 

input.scan(/[A-Z]+ \d+/) 
    .map{ |str| str.split(' ') } 
    .group_by{ |letter, _| letter } 
    .each do |letter, pairs| 
    print letter 
    print ' ' 
    puts pairs.map{ |_, number| number }.sort.join(' ') 
end 
#=> 
# A 1 2 
# B 3 7 
# C 2 5 
1
h = Hash.new { |h,k| h[k] = [] } 
input = ['A 1', 'B 3', 'C 5', 'A 2', 'B 7', 'C 2'].join("\n") 
input.each_line { |x| h[$1] << $2 if x =~ /^(.*?)\s+(.*?)$/ } 

h.keys.sort.each do |k| 
    puts ([k] + h[k].sort).join(' ') 
end 

# A 1 2 
# B 3 7 
# C 2 5 

 Смежные вопросы

  • Нет связанных вопросов^_^