-
-
Save zaki/3872038 to your computer and use it in GitHub Desktop.
static VALUE | |
rb_ary_transpose_test(VALUE ary) | |
{ | |
long elen = -1, alen, i, j, k; | |
VALUE tmp, result = 0; | |
// get the longest sub-array so we know how much to extend to | |
long elen_max = -1; | |
for (i=0; i<alen; i++) { | |
tmp = to_ary(rb_ary_elt(ary, i)); | |
long length = RARRAY_LEN(tmp); | |
if (elen_max < length) { | |
elen_max = length; | |
} | |
} | |
alen = RARRAY_LEN(ary); | |
if (alen == 0) return rb_ary_dup(ary); | |
for (i=0; i<alen; i++) { | |
tmp = to_ary(rb_ary_elt(ary, i)); | |
if (elen < 0) { /* first element */ | |
elen = RARRAY_LEN(tmp); | |
result = rb_ary_new2(elen); | |
for (j=0; j<elen; j++) { | |
rb_ary_store(result, j, rb_ary_new2(alen)); | |
} | |
} | |
for (j=0; j<elen; j++) { | |
long len = RARRAY_LEN(tmp); | |
if (len < elen_max) { | |
if (!rb_block_given_p()) { | |
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld) and no block was given", | |
RARRAY_LEN(tmp), elen); | |
} | |
else { | |
for(k = len; k < elen_max; k++) { | |
// fill in missing elements | |
VALUE filler = rb_yield(rb_ary_new3(2L, LONG2FIX(i), LONG2FIX(k))); | |
rb_ary_push_1(tmp, filler); | |
} | |
} | |
} | |
rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j)); | |
} | |
} | |
return result; | |
} | |
rb_define_method(rb_cArray, "transpose_test", rb_ary_transpose_test, 0); |
require 'test/unit' | |
class TestArray < Test::Unit::TestCase | |
def setup | |
@verbose = $VERBOSE | |
$VERBOSE = nil | |
@cls = Array | |
end | |
def teardown | |
$VERBOSE = @verbose | |
end | |
# LOTS OF OTHER TESTS | |
def test_transpose | |
assert_equal([[1, :a], [2, :b], [3, :c]], | |
[[1, 2, 3], [:a, :b, :c]].transpose_test) | |
assert_raise(IndexError) { [[1, 2, 3], [:a, :b]].transpose_test } | |
end | |
def test_transpose_with_block | |
assert_equal([[1, :a], [2, :b], [3, :hoge]], | |
[[1,2,3], [:a, :b]].transpose_test { |x, y| :hoge }) | |
end | |
def test_transpose_block_parameters | |
[[1, :a], [2, :b], [3]].transpose_test do |x, y| | |
assert_equal(2, x) | |
assert_equal(1, y) | |
:foo | |
end | |
end | |
def test_transpose_block_parameters | |
arr = [[1, nil, :a], [nil, :b], [3]].transpose_test do |x, y| | |
:foo | |
end | |
assert_equal([ | |
[1, nil, 3], | |
[nil, :b ,:foo], | |
[:a, :foo, :foo] | |
], arr) | |
end | |
#LOTS OF OTHER TESTS | |
end |
randym
commented
Oct 11, 2012
module Transposer
def self.transpose array
return array.clone if array.size == 0
rows = array.size
columns = array.map { |item| item.size }.max
result = Array.new(columns) { Array.new(rows) }
0...rows.times do |row_index|
0...columns.times do |column_index|
result[column_index][row_index] =
if array.size > row_index && array[row_index].size > column_index
array[row_index][column_index]
elsif block_given?
yield(column_index, row_index)
else
raise ArgumentError, 'your array sucks'
end
end
end
result
end
end
require 'test/unit'
class TestTransposer < Test::Unit::TestCase
def test_transpose_empty
assert(Transposer::transpose(Array.new).is_a?(Array))
end
def test_transpose_simple
assert_equal(Transposer.transpose([[1,2], [3,4]]), [[1, 3], [2, 4]])
end
def test_transpose_with_block
assert_equal(Transposer.transpose([[1], [3, 4]]) { |x, y| 2 },
[[1,3],[2,4]])
end
end
module Transposer
def self.transpose array
return array.clone if array.size == 0
rows = array.size
columns = array.map { |item| item.size }.max
result = Array.new(columns) { Array.new(rows) }
0...rows.times do |row_index|
0...columns.times do |column_index|
result[column_index][row_index] =
if array.size > row_index && array[row_index].size > column_index
array[row_index][column_index]
elsif block_given?
yield(column_index, row_index)
else
raise ArgumentError, 'your array sucks'
end
end
end
result
end
end
require 'test/unit'
class TestTransposer < Test::Unit::TestCase
def test_transpose_empty
assert(Transposer::transpose(Array.new).is_a?(Array))
end
def test_transpose_simple
assert_equal(Transposer.transpose([[1,2], [3,4]]), [[1, 3], [2, 4]])
end
def test_transpose_with_block
assert_equal(Transposer.transpose([[1], [3, 4]]) { |x, y| 2 },
[[1,3],[2,4]])
end
end