Rubyで要素数が異なる配列をtransposeする6つの方法(ベンチマークとテスト付き)

f:id:ihatov08:20171003121303j:plain

Rubyで要素数が異なる配列をtransposeする6つの方法です。(ベンチマークとテスト付きです)

コード

require 'benchmark'
require 'test/unit'
module SafeTranspose
refine Array do
def a
max_length = max_by(&:size).size
map { |value| Array.new(max_length) { |i| value[i] || '' } }.transpose
end
def b
max_length = max_by(&:size).size
map { |m| m.fill('', m.size, max_length - m.size) }.transpose
end
# def c
#   # 先頭要素が最長である必要があるので却下
#   self[0].zip(*self[1..-1])
# end
def d
max_length = max_by(&:size).size
map { |e| e.values_at(0...max_length) }.transpose
end
def e
max_length = max_by(&:size).size
Array.new(max_length) { |i| map { |e| e[i] } }
end
def f
result = []
max_size = max_by(&:size).size
max_size.times do |i|
result[i] = Array.new(first.size)
each_with_index { |r, j| result[i][j] = r[i] }
end
result
end
end
end
using SafeTranspose
array = []
90000.times do
array.push((1..rand(10)).to_a)
end
Benchmark.bm 10 do |r|
('a'..'f').to_a.each do |m|
next if m == 'c'
r.report m do
array.send(m)
end
end
end
class SafeTransposeTest < Test::Unit::TestCase
using SafeTranspose
@@array = []
10.times do
@@array.push((1..rand(10)).to_a)
end
('a'..'f').each do |m|
next if m == 'c'
define_method("test_#{m}") do
assert_equal @@array.a, @@array.send(m)
end
end
end

結果

                 user     system      total        real
a            0.180000   0.020000   0.200000 (  0.203185)
b            0.090000   0.000000   0.090000 (  0.093895)
d            0.110000   0.010000   0.120000 (  0.116067)
e            0.120000   0.000000   0.120000 (  0.124450)
f            0.190000   0.010000   0.200000 (  0.195936)
Loaded suite safe_transpose_test
Started
.....
Finished in 0.001421 seconds.
---------------------------------------------------------------------------------------------------------------------------------------
5 tests, 5 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
---------------------------------------------------------------------------------------------------------------------------------------
3518.65 tests/s, 3518.65 assertions/s

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です