我怀疑有一种更清洁,更惯用的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}}
对正在发生的事情的解释
"2 6 4\n7 9 8"
=>由new-line => ["2 6 4", "7 9 8"]
分割' '
=> [["2", "6", "4"], ["7", "9", "8"]]
int
s(每行发生一次)我觉得这段代码不是很易读,但我来自生锈,所以我不习惯好的风格
我对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 ) )
你的代码看起来很好。
in_string.split(/\n/).map { |row| row.split.map(&:to_i) }
我们通常只是避免使用{}
的多行块。将do-end
用于多行块。
我找到了两个小改进
split
默认参数是' '
map(&:to_i)
我觉得这很好。如果你认为嵌套块不好读。你可以定义一个像这样的方法
def to_int_arr(str)
str.split(' ').map(&:to_i)
end
in_string.split(/\n/).map{|str| to_int_arr(str)}
顺便说一句,更好地在多行块中使用do end
Ruby具有很多用于“清洁可读性”的便利内置插件,例如
each_line
和split
的默认参数.to_proc
捷径,&
input = "2 6 4\n7 9 8"
input.each_line.map { |line| line.split.map(&:to_i) }
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]]