Сортировка табло по имени и оценка с помощью ruby

у меня есть текстовый файл, который состоит из них:

player1
10
player2
13
player3
60

Это имя игрока и счет. Например, счет игрока 1 равен 10, а счет игрока 2 — 13 и так далее. Я хочу отсортировать текстовый файл по счету. Например:

player3 60
player2 13
player1 10

Вы не можете отсортировать файл сразу. Вы должны прочитать текстовый файл и проанализировать пары имя-оценка в сортируемую структуру данных, такую ​​как массив. Вы, наверное, уже пробовали что-то сами. Покажите свои попытки, пожалуйста.

Stefan 21.05.2019 08:56
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
1
168
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Базовая реализация этого случая может быть примерно такой:

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"], кстати сортировка работает

David Lee 21.05.2019 15:12

Другие вопросы по теме