В Ruby идиоматически и аккуратно улучшено это использование split и map, чтобы превратить ввод строки в массив 2d int (то есть матрицу) - PullRequest
0 голосов
/ 17 апреля 2019

Я подозреваю, что есть более чистый, более идиоматичный, Ruby-способ решить эту загадку, чем то, что я сделал. Я слишком новичок в Руби, чтобы подтвердить. Все мои поиски не касались вопроса о том, как лучше написать Ruby в приведенных ниже примерах.

Загадка, мне нужно взять строковый ввод и превратить его в матрицу. Строки разделены '\n', элементы строки - ' '

например. строковый ввод "2 6 4\n7 9 8" имеет вывод [[2, 6, 4], [7, 9, 8]] Т.е. матрица:

2 6 4
7 9 8

Это мое решение:

@rows = in_string.split(/\n/).map{|str| str.split(' ').map{|ch| ch.to_i}}

Объяснение того, что происходит

  1. "2 6 4\n7 9 8" => разделить на новую строку => ["2 6 4", "7 9 8"]
  2. отобразить элементы от 1. до разделения на ' ' => [["2", "6", "4"], ["7", "9", "8"]]
  3. отобразить элементы 2., чтобы они стали int с (это происходит один раз для каждой строки)
  4. фин. У нас есть результат, который мы после

Мне кажется, что этот код не очень читабелен, но я пришел из ржавчины, поэтому я не привык к хорошему стилю

Я недостаточно знаком с Ruby, чтобы понять хорошие способы написания таких решений. Я пытался использовать больше строк, как это

@rows = in_string.split(/\n/).map{
            |str| str.split(' ').map{
                |ch| ch.to_i
            }
         }

Но я все еще чувствую себя оставленным в темноте от того, что можно считать хорошим стилем, или какие другие варианты доступны.

Правильность кода в порядке. Для меня отличный ответ - это тот, который даст мне понимание того, на что нужно обращать внимание при рассмотрении подобных проблем в будущем, и больше уверенности в моем понимании того, что делает элегантный код Ruby.

РЕДАКТИРОВАТЬ из ответов Пока что предложений

  • использовать значение по умолчанию для разделения
  • использовать значения по умолчанию на карте
  • используйте do-end (я еще учусь). Если кто-то захочет это отредактировать, просто фантастика.

Вот чем я закончил: @rows = in_string.split(/\n/).map( |chrs| chrs.split.map( &:to_i ) )

Ответы [ 4 ]

0 голосов
/ 19 апреля 2019
str = "2 6 4\n7 9 8\n"

arr = str.split.map(&:to_i)
  #=> [2, 6, 4, 7, 9, 8]
arr.each_slice(arr.size/str.lines.size).to_a
  #=> [[2, 6, 4], [7, 9, 8]]
0 голосов
/ 17 апреля 2019

Я думаю, что это достаточно хорошо. если вы думаете, что вложенный блок не подходит для чтения. Вы можете определить метод как

def to_int_arr(str)
  str.split(' ').map(&:to_i)
end

in_string.split(/\n/).map{|str| to_int_arr(str)}

Кстати, лучше использовать do end в многострочном блоке

0 голосов
/ 18 апреля 2019

В Ruby имеется множество удобных встроенных функций для «чистой читабельности», например,

  • аргументы по умолчанию для each_line и split
  • символов с .to_proc ярлык, &
input = "2 6 4\n7 9 8"

input.each_line.map { |line| line.split.map(&:to_i) }
0 голосов
/ 17 апреля 2019

Твой код мне подходит.

in_string.split(/\n/).map { |row| row.split.map(&:to_i) }

Обычно мы просто избегаем многострочных блоков с {}. Используйте do-end для многострочных блоков.

Два небольших улучшения, которые я нашел

  • split параметр по умолчанию ' '
  • Если вам не нужен блок, не используйте его. Просто передайте ему проц map(&:to_i)
...