在 Ruby 中,习惯性地、干净地改进了这种使用 split 和 map 将字符串输入转换为 2d int 数组(即矩阵



我怀疑有一种比我做的更干净、更惯用的 Ruby 方法来解决这个难题。不过,我对 Ruby 来说太新了,无法确认。我所有的搜索都没有解决如何在下面给出的例子中最好地编写 Ruby 的问题。

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

例如,字符串输入"2 6 4n7 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 4n7 9 8"=> 按换行符拆分 =>["2 6 4", "7 9 8"]
  2. 映射从 1. 到拆分的元素' '=>[["2", "6", "4"], ["7", "9", "8"]]
  3. 映射 2. 的元素以变为ints(每行发生一次)
  4. 鳍。我们有我们追求的结果

我觉得这段代码不是很好读,但我来自 rust,所以我不习惯好的风格

我对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_linesplit的默认参数
  • 带有.to_proc快捷方式的符号,&
input = "2 6 4n7 9 8"
input.each_line.map { |line| line.split.map(&:to_i) }
str = "2 6 4n7 9 8n"
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]]

最新更新