patternrubyMinor
Transposing a 2D array
Viewed 0 times
arraytransposingstackoverflow
Problem
Would you have any suggestions for improvements for the code below?
def my_transpose(arr)
# number of rows
m = arr.count
#number of columns
n = arr[0].count
transposed_arr = Array.new(n) { Array.new(m) }
# loop through the rows
arr.each_with_index do |row, index1|
# loop through the colons of one row
row.each_with_index do |num, index2|
# swap indexes to transpose the initial array
transposed_arr[index2][index1] = num
p transposed_arr
end
end
transposed_arr
endSolution
As already mentioned, Ruby's
But, for the purposes of an exercise, there are multiple ways to do the same thing.
For instance, one way (which only works for square matrices!) is to use
Or you can use
Or do basially the same thing, just using
But keeping more of your code, you could use
For instance:
Of course, you'll want to check a few things. Firstly, whether there are any rows in the matrix at all (if not, the
There are yet more ways to do things, but again: It's already built in as
Array comes with a built-in #transpose method.But, for the purposes of an exercise, there are multiple ways to do the same thing.
For instance, one way (which only works for square matrices!) is to use
#map:def my_transpose(arr)
arr.each_with_index.map do |_, index|
arr.map { |row| row[index] }
end
endOr you can use
reduce (this will work for rectangular matrices):def my_transpose(arr)
arr.reduce([]) do |transposed, row|
row.each_with_index do |value, col|
transposed[col] ||= []
transposed[col] << value
end
transposed
end
endOr do basially the same thing, just using
each_with_object:def my_transpose(arr)
arr.each_with_object([]) do |row, transposed|
row.each_with_index do |value, col|
transposed[col] ||= []
transposed[col] << value
end
end
endBut keeping more of your code, you could use
Array#new as your loop, since it accepts a block.For instance:
def my_transpose(arr)
rows = arr.count
cols = arr.first.count
Array.new(cols) do |col|
Array.new(rows) do |row|
arr[row][col]
end
end
endOf course, you'll want to check a few things. Firstly, whether there are any rows in the matrix at all (if not, the
arr[0].count will fail), and whether the matrix is actually rectangular:def my_transpose(arr)
return [] if arr.empty?
rows = arr.count
cols = arr.first.count
raise ArgumentError unless arr.all? { |row| row.count == cols }
Array.new(cols) do |col|
Array.new(rows) do |row|
arr[row][col]
end
end
endThere are yet more ways to do things, but again: It's already built in as
arr.transpose.Code Snippets
def my_transpose(arr)
arr.each_with_index.map do |_, index|
arr.map { |row| row[index] }
end
enddef my_transpose(arr)
arr.reduce([]) do |transposed, row|
row.each_with_index do |value, col|
transposed[col] ||= []
transposed[col] << value
end
transposed
end
enddef my_transpose(arr)
arr.each_with_object([]) do |row, transposed|
row.each_with_index do |value, col|
transposed[col] ||= []
transposed[col] << value
end
end
enddef my_transpose(arr)
rows = arr.count
cols = arr.first.count
Array.new(cols) do |col|
Array.new(rows) do |row|
arr[row][col]
end
end
enddef my_transpose(arr)
return [] if arr.empty?
rows = arr.count
cols = arr.first.count
raise ArgumentError unless arr.all? { |row| row.count == cols }
Array.new(cols) do |col|
Array.new(rows) do |row|
arr[row][col]
end
end
endContext
StackExchange Code Review Q#87043, answer score: 7
Revisions (0)
No revisions yet.