在Ruby中,通过使用split和map将字符串输入转换为2d int数组(即矩阵)的惯用和干净改进

问题描述 投票:0回答:4

我怀疑有一种更清洁,更惯用的Ruby方式来解决这个难题而不是我所做的。不过,我对Ruby太新了,要确认一下。我在下面给出的例子中没有解决如何最好地编写Ruby的问题。

谜题是,我需要采用字符串输入并将其转换为矩阵。行由'\n'分隔,行元素由' '分隔

例如。字符串输入"2 6 4\n7 9 8"输出[[2, 6, 4], [7, 9, 8]] I.e.矩阵:

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" =>由new-line => ["2 6 4", "7 9 8"]分割
  2. 映射元素从1.分割为' ' => [["2", "6", "4"], ["7", "9", "8"]]
  3. 映射到2.的元素成为ints(每行发生一次)
  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 ) )

ruby closures string-parsing idioms readability
4个回答
0
投票

你的代码看起来很好。

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

我们通常只是避免使用{}的多行块。将do-end用于多行块。

我找到了两个小改进

  • split默认参数是' '
  • 如果您不需要块,请不要使用它。只需将过程传递给它map(&:to_i)

0
投票

我觉得这很好。如果你认为嵌套块不好读。你可以定义一个像这样的方法

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

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

顺便说一句,更好地在多行块中使用do end


0
投票

Ruby具有很多用于“清洁可读性”的便利内置插件,例如

  • each_linesplit的默认参数
  • 符号与.to_proc捷径,&
input = "2 6 4\n7 9 8"

input.each_line.map { |line| line.split.map(&:to_i) }

0
投票
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]]
© www.soinside.com 2019 - 2024. All rights reserved.