我想要一个2d数组初始化如下
1 0 0 0
0 2 0 0
0 0 3 0
0 0 0 4
给出输入字符串"1234"
时。
我的功能如下
def fun(str)
maxlength = Array.new(str.length,Array.new(str.length,0))
(0..str.length-1).each do |i|
maxlength[i][i] = str[i].to_i
end
print maxlength
end
print fun("1234")
这给了我
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
这不是我想要的。
如何获得我想要的输出?
答案 0 :(得分:7)
我建议你使用类方法Matrix::diagonal:
require 'Matrix'
str = "1234"
Matrix.diagonal(*(str.chars.map(&:to_i))).to_a
# => [[1, 0, 0, 0],
# [0, 2, 0, 0],
# [0, 0, 3, 0],
# [0, 0, 0, 4]]
另一种方式:
Array.new(str.size) {|i| Array.new(str.size) {|j| (i==j) ? str[i].to_i : 0}}
# => [[1, 0, 0, 0],
# [0, 2, 0, 0],
# [0, 0, 3, 0],
# [0, 0, 0, 4]]
答案 1 :(得分:5)
这里最大的问题是你不是像你想象的那样创建一个二维数组,而是你正在创建两个数组。这是因为你将一个奇异的数组作为默认值传入,而不是一个可以生成它们的块。
你期待的是:
array1 = [ array21, array22, array23, array24 ]
你实际得到的是:
array1 = [ array2, array2, array2, array2 ]
通过将最后一个参数转换为块来轻松修复:
def fun(str)
maxlength = Array.new(str.length) { Array.new(str.length,0) }
str.chars.collect(&:to_i).each_with_index do |v,i|
maxlength[i][i] = v
end
print maxlength
end
print fun("1234")
我也转而使用chars
,根据需要拆分字符串。
所以问题是你正确设置了位置,但由于所有二级数组都是同一个数组,你没有得到你期望的结果。
更新:在Chris的回答中添加了each_with_index
,这使得这项工作可以使用任意数字。
答案 2 :(得分:2)
另一个单行代表:
"1234".chars.map.with_index {|v, i| Array.new(4, 0).tap {|a| a[i] = v.to_i } }
这只创建N个数组,每个字符对应一个字符串,并将每个数组的i
索引设置为字符串中该字符的值。
编辑:另一个有趣的解决方案:
"1234".chars.map.with_index {|c, i| [c.to_i].fill(0, 1..4).rotate(-i) }
这会创建四个由[value, 0, 0, 0]
组成的数组,然后使用Array#rotate
将值移动到正确的位置。
另一个解决方案,它利用了每对非零值之间有四个0值的事实:
"1234".chars.flat_map {|c| [c.to_i].fill(0, 1..4) }.each_slice(4).take(4)