Skip to content

@randym /transpose.rb
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Array#transpose that accepts a block for populating missing elements
class Array
# A more meaningful message when you have an insufficient number of columns
# in a row for transposition.
MSG_TRANSPOSE_INDEX_ERROR = "Row %s has only %s element(s), but transposition
requires %s. Please specify a block to populate missing items or adjust
your array to contain an equal number of elements in each row array."
# Overrides the default transpose method to allow a block that can be used to return
# elements required to populate the transposition.
# @example Using Transpose
# > [[1, 2], [3, 4]].transpose
# => [[1, 3], [2, 4]]
#
# > [[1], [3, 4]].transpose
# IndexError: Row 0 has only 1 element(s), but transposition requires 2...
#
# > [[1,], [3, 4]].transpose { |x, y| 2 }
# => [[1, 3], [2, 4]]
# @note
# When yielding to the block the column(x) and row(y) index for the
# missing element are provided
# @return [Array] The transposed array
def transpose
return clone if size == 0
rows = size
columns = map(&:size).max
result = Array.new(columns) { Array.new(rows) }
0...rows.times do |row_index|
0...columns.times do |column_index|
datum = if self[row_index].size > column_index
self[row_index][column_index]
elsif block_given?
yield(column_index, row_index)
else
raise IndexError, MSG_TRANSPOSE_INDEX_ERROR %
[row_index,
self[row_index].size,
columns]
end
result[column_index][row_index] = datum
end
end
result
end
end
require 'test/unit'
class TestArray < Test::Unit::TestCase
def test_transpose_empty
assert(Array.new.transpose.is_a?(Array))
end
def test_transpose_simple
assert_equal([[1, 2], [3, 4]].transpose,
[[1, 3], [2, 4]])
end
def test_transpose_with_block
filled = [[1], [3, 4]].transpose { |x, y| 2 }
assert_equal([[1, 3],[2, 4]], filled)
end
def test_your_array_sucks
assert_raise(IndexError) do
[[1, 2], [1]].transpose
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.