Базовая реализация этого случая может быть примерно такой:
def main
file = File.new("score.txt", "r")
players = Array.new
score = Array.new
number_regex = /\A[-+]?[0-9]*\.?[0-9]+\Z/
file.each_line do |line|
if (line.match(number_regex))
score << line.delete(" \t\r\n")
else
players << line.delete(" \t\r\n")
end
end
file.close
result = Hash.new
i = 0
while i < players.length
result[players[i]] = score[i]
i += 1
end
print_score(result)
end
def print_score(hash)
hash.each do |key,value|
puts key + ": " + value
end
end
main
Но предупреждаю!!! Это просто базовая реализация. У этого решения есть некоторые побочные эффекты, например, если последовательность данных будет нарушена, этот алгоритм перестанет работать.
player1
10
player2
player3
60
Чтобы реализовать полностью работающее решение, вам нужно проверять следующую строку при чтении каждой строки и проверять ее на содержание желаемых значений. Если последовательность нарушена, и после значения «playerN» не идет количество набранных очков, то считать в этом случае их отсутствие за 0. В общем, создать целостное решение в данном случае — задача не из легких. А для того, чтобы выбрать оптимальное решение, по сути, вы не предоставили достаточно данных. Откуда записывается учетная запись .txt? Можно ли изменить источник записи? И так далее
Вам нужно прочитать файл в массив, выполнить некоторые манипуляции, а затем записать обратно в файл. Предполагая, что исходный файл содержит пары строк, как показано.
Сначала прочитайте строки файла в массив Файл#readlines (обратите внимание, chomp: true
для зачистки "\n"
).
data = File.readlines('score.txt', chomp: true)
#=> ["player1", "10", "player2", "13", "player3", "60"]
Получив массив, сгруппируйте каждые два элемента (Перечисляемый#each_slice) и отсортируйте по второму элементу, рассматриваемому как целое число (.to_i
) (Перечислимое#sort_by). Обратите внимание на знак -
, чтобы изменить порядок сортировки на обратный. В качестве последней операции map
(Перечислимая#карта) для join
пары элементов во вложенном массиве (Массив # присоединиться):
score_sorted = data.each_slice(2).sort_by { |_, score| -score.to_i}.map{ |ary| ary.join(' ') }
#=> ["player3 60", "player2 13", "player1 10"]
Наконец, запишите массив обратно в файл (Файл#открыть):
File.open("score_sorted.txt", "w+") { |f| f.puts score_sorted }
я использовал код из вашей помощи score_sorted = data.each_slice(2).sort_by { |_, score| -score.to_i}.map{ |ary| ary.join(' ') }
, но вывод ["player1", "10", "player2", "13", "player3", "60"] вместо ["player3 60", "player2 13" ,"player1 10"], кстати сортировка работает
Вы не можете отсортировать файл сразу. Вы должны прочитать текстовый файл и проанализировать пары имя-оценка в сортируемую структуру данных, такую как массив. Вы, наверное, уже пробовали что-то сами. Покажите свои попытки, пожалуйста.