Ruby 将二维数组的子数组压缩在一起
有没有一种通用的方法 每个子数组的长度相同Ruby 将二维数组的子数组压缩在一起,ruby,arrays,list,Ruby,Arrays,List,有没有一种通用的方法 每个子数组的长度相同 c = [[1,1,1,1], [2,2,2,2], [3,3,3,3]] c[0].zip(c[1], c[2]) => [[1,2,3][1,2,3],[1,2,3],[1,2,3]] 谢谢。要使用zip: c.first.zip(*c.drop(1)) 否则, c.transpose 将是一种对称方式。要使用zip: c.first.zip(*c.drop(1)) 否则, c.transpose 将是一种对称的方式。编辑:我发
c = [[1,1,1,1], [2,2,2,2], [3,3,3,3]]
c[0].zip(c[1], c[2])
=> [[1,2,3][1,2,3],[1,2,3],[1,2,3]]
谢谢。要使用
zip
:
c.first.zip(*c.drop(1))
否则,
c.transpose
将是一种对称方式。要使用
zip
:
c.first.zip(*c.drop(1))
否则,
c.transpose
将是一种对称的方式。编辑:我发现了为什么我的方法如此快速,这可能会产生好的和坏的影响,这取决于结果的使用方式。假设
c = [[1,1,1],[2,2,2]]
然后
其中:
a = b = c = [1,2]
但那是因为:
a.object_id = b.object_id = c.object.id
因此,“坏”是指如果d
的一个元素被更改,则该行中的所有元素都更改为相同的值。“好”是,如果数组d
不会更改,则此方法不仅速度快,而且只需很少的存储即可保存结果数组d
的(表示)
然而,事实是,如果不改变d
,那么创建它是毫无意义的。相反,应该重构代码,以便在后续操作中只使用d
的第一个元素。(这句话当然适用于所有方法。)
编辑结束
如果您希望c
的每个元素(行)包含彼此相等的元素,并且它们的大小都相同,如您的示例所示,则可以执行以下操作:
[c.map(&:first)]*c.first.size
出于好奇,我决定对这个方法和@sawa提供的两个方法进行基准测试
基准测试代码
require 'benchmark'
def sawa_zip(c) c.first.zip(*c.drop(1)) end
def sawa_transpose(c) c.transpose end
def cary(c) [c.map(&:first)]*c.first.size end
def bench_em(n, m, iterations)
puts "n = #{n}, m = #{m}, interations = #{iterations}\n"
c = n.times.map { Array.new }.map.with_index { |_,i| Array.new(m,i) }
Benchmark.bm(%w[sawa_zip, sawa_transpose, cary].map(&:size).max) do |bm|
bm.report('sawa_zip') do
iterations.times do
sawa_zip(c)
end
end
bm.report('sawa_transpose') do
iterations.times do
sawa_transpose(c)
end
end
bm.report('cary') do
iterations.times do
cary(c)
end
end
end
end
bench_em(200, 300,5)
bench_em(2000, 3000,5)
bench_em(10000, 15000,1)
基准结果
应该记住,只有当矩阵每行中的所有元素相等时,这种比较才有效。我原以为我建议的方法会比较快,但没有结果显示的那么快
n = 200, m = 300, interations = 5
user system total real
sawa_zip 0.010000 0.000000 0.010000 ( 0.007858)
sawa_transpose 0.000000 0.000000 0.000000 ( 0.006568)
cary 0.000000 0.000000 0.000000 ( 0.000113)
n = 2000, m = 3000, interations = 5
user system total real
sawa_zip 1.010000 0.070000 1.080000 ( 1.080286)
sawa_transpose 0.800000 0.060000 0.860000 ( 0.860823)
cary 0.000000 0.000000 0.000000 ( 0.001669)
n = 10000, m = 15000, interations = 1
user system total real
sawa_zip 25.760000 0.740000 26.500000 ( 26.668127)
sawa_transpose 18.200000 0.630000 18.830000 ( 18.870150)
cary 0.000000 0.000000 0.000000 ( 0.002412)
编辑:我发现了为什么我的方法如此之快,这可能有好有坏的影响,这取决于结果的使用方式。假设
c = [[1,1,1],[2,2,2]]
然后
其中:
a = b = c = [1,2]
但那是因为:
a.object_id = b.object_id = c.object.id
因此,“坏”是指如果d
的一个元素被更改,则该行中的所有元素都更改为相同的值。“好”是,如果数组d
不会更改,则此方法不仅速度快,而且只需很少的存储即可保存结果数组d
的(表示)
然而,事实是,如果不改变d
,那么创建它是毫无意义的。相反,应该重构代码,以便在后续操作中只使用d
的第一个元素。(这句话当然适用于所有方法。)
编辑结束
如果您希望c
的每个元素(行)包含彼此相等的元素,并且它们的大小都相同,如您的示例所示,则可以执行以下操作:
[c.map(&:first)]*c.first.size
出于好奇,我决定对这个方法和@sawa提供的两个方法进行基准测试
基准测试代码
require 'benchmark'
def sawa_zip(c) c.first.zip(*c.drop(1)) end
def sawa_transpose(c) c.transpose end
def cary(c) [c.map(&:first)]*c.first.size end
def bench_em(n, m, iterations)
puts "n = #{n}, m = #{m}, interations = #{iterations}\n"
c = n.times.map { Array.new }.map.with_index { |_,i| Array.new(m,i) }
Benchmark.bm(%w[sawa_zip, sawa_transpose, cary].map(&:size).max) do |bm|
bm.report('sawa_zip') do
iterations.times do
sawa_zip(c)
end
end
bm.report('sawa_transpose') do
iterations.times do
sawa_transpose(c)
end
end
bm.report('cary') do
iterations.times do
cary(c)
end
end
end
end
bench_em(200, 300,5)
bench_em(2000, 3000,5)
bench_em(10000, 15000,1)
基准结果
应该记住,只有当矩阵每行中的所有元素相等时,这种比较才有效。我原以为我建议的方法会比较快,但没有结果显示的那么快
n = 200, m = 300, interations = 5
user system total real
sawa_zip 0.010000 0.000000 0.010000 ( 0.007858)
sawa_transpose 0.000000 0.000000 0.000000 ( 0.006568)
cary 0.000000 0.000000 0.000000 ( 0.000113)
n = 2000, m = 3000, interations = 5
user system total real
sawa_zip 1.010000 0.070000 1.080000 ( 1.080286)
sawa_transpose 0.800000 0.060000 0.860000 ( 0.860823)
cary 0.000000 0.000000 0.000000 ( 0.001669)
n = 10000, m = 15000, interations = 1
user system total real
sawa_zip 25.760000 0.740000 26.500000 ( 26.668127)
sawa_transpose 18.200000 0.630000 18.830000 ( 18.870150)
cary 0.000000 0.000000 0.000000 ( 0.002412)
c
中的数组总是大小相同的?c。转置
是您所需要的全部,即使您选择了一个答案,请回答@toro2k的问题,并回答另一个问题:您是否希望c的每一行都有相等的元素(例如,[2,2,2,2,2]?我这样问是因为我刚刚发布的答案是另一种方式,如果你的答案是“是”,那么你可以做你想做的事情对于这两个问题。更一般地说,因为其他人将来会阅读您的问题,所以清楚一点很重要。c
中的数组总是大小相同?c。即使您选择了一个答案,也只需要转置,请回答@toro2k的问题,还有一个问题:您是否打算让c的每一行都有相等的e元素(例如,[2,2,2,2]?我这样问是因为我刚才发布的答案是另一种方式,如果你的答案是“是”,那么你可以做你想做的事情对于这两个问题。更一般地说,正如其他人将来会阅读你的问题一样,清楚是很重要的。#zip
是好的和安全的。#转置
不安全,如果数组大小不同。+1表示#zip
。太好了。谢谢。#zip
是好的和安全的。#转置
不安全,如果数组不安全大小不一..+1用于#zip
。太棒了。谢谢。