Просьба уточнить ваш вопрос.
Нужны ли идентификаторы и ответы? они всегда попарно? Является ли символ "_"
всегда используемым как разделитель (это означает, что ответы должны быть закодированы)? Является ли формат всегда:
"ID:#{id_mumber}_#{answer in text}"
... "_"
... *
я буду считать, ответ на все вопросы, которые я задал в «Да», но если я ошибаюсь, пожалуйста, измените ваш вопрос оставьте мне комментарий - я отредактирую ответ.
s = "ID:1_Answer1_ID:2_Answer2_ID:3_AnswerRandom_ID:789_Answer3.5"
answer_hash = {}
tmp = s.split('_')
answer_hash[tmp.shift[3..-1].to_i] = tmp.shift while tmp[0]
answer_hash # => {1=>"Answer1", 2=>"Answer2", 3=>"AnswerRandom", 789=>"Answer3.5"}
answer_hash.keys # => [1, 2, 3, 789]
answer_hash.values # => ["Answer1", "Answer2", "AnswerRandom", "Answer3.5"]
EDIT
Я любил @ ответ NDN в использовании Regexp ... Это ясно, но может быть медленнее для коротких строк.
Вот тесты на моей машине - Они показывают, что разница в производительности в основном для коротких строк ID:
s = "ID:1_Answer1_ID:2_Answer2_ID:3_AnswerRandom_ID:789_Answer3.5"
puts Benchmark.measure {100_000.times {answer_hash = {}; tmp = s.split('_'); answer_hash[tmp.shift[3..-1].to_i] = tmp.shift while tmp[0] } }
# ### Short string using str
# => 0.280000 0.000000 0.280000 ( 0.286917)
puts Benchmark.measure {100_000.times {ids, answers = *s.scan(/(?<=ID:)(\d+)_([^_]+)/).transpose } }
# ### Short string using string.scan Regexp
# => 0.590000 0.000000 0.590000 ( 0.595052)
s = []
100.times {|i| s << ("ID:#{i}_Answer#{i}") }
s = s.join('_')
puts Benchmark.measure {100_000.times {answer_hash = {}; tmp = s.split('_'); answer_hash[tmp.shift[3..-1].to_i] = tmp.shift while tmp[0] } }
# ### Medium string using string.split
# => 7.180000 0.010000 7.190000 ( 7.213266)
puts Benchmark.measure {100_000.times {ids, answers = *s.scan(/(?<=ID:)(\d+)_([^_]+)/).transpose } }
# ### Medium string using string.scan Regexp
# => 8.860000 0.020000 8.880000 ( 8.888352)
s = []
1000.times {|i| s << ("ID:#{i}_Answer#{i}") }
s = s.join('_')
puts Benchmark.measure {1000.times {answer_hash = {}; tmp = s.split('_'); answer_hash[tmp.shift[3..-1].to_i] = tmp.shift while tmp[0] } }
# ### Long string using string.split (shorter benchmark)
# => 0.690000 0.000000 0.690000 ( 0.693698)
puts Benchmark.measure {1000.times {ids, answers = *s.scan(/(?<=ID:)(\d+)_([^_]+)/).transpose } }
# ### Long string using string.scan Regexp (shorter benchmark)
# => 0.900000 0.000000 0.900000 ( 0.901358)
хорошее решение и хорошее объяснение. –
Очень чистое решение. Спасибо огромное! – rak
Однако он не фиксирует пустое значение ответа. Например, вопрос 1 не имеет ответа. s = "ID: 1__ID: 2_Answer2_ID: 3_AnswerRandom_ID: 789_Answer3.5" – rak