Skip to content

Each_with_index #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 78 additions & 54 deletions lib/matrix/matrix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,61 +112,17 @@ def self.convert(matrix)
fast_matrix
end

#
#
# Yields all elements of the matrix, starting with those of the first row
#
# Matrix[ [1,2], [3,4] ].each { |e| puts e }
# # => prints the numbers 1 to 4
def each(which = :all) # :yield: e
return to_enum :each, which unless block_given?
case which
when :all
(0...row_count).each do |i|
(0...column_count).each do |j|
yield self[i, j]
end
end
when :diagonal
(0...[row_count, column_count].min).each do |i|
yield self[i, i]
end
when :off_diagonal
(0...row_count).each do |i|
(0...column_count).each do |j|
if i != j
yield self[i, j]
end
end
end
when :lower
(0...row_count).each do |i|
(0..[i,column_count-1].min).each do |j|
yield self[i, j]
end
end
when :strict_lower
(1...row_count).each do |i|
(0...[i,column_count].min).each do |j|
yield self[i, j]
end
end
when :strict_upper
(0...row_count).each do |i|
(i+1...column_count).each do |j|
yield self[i, j]
end
end
when :upper
(0...row_count).each do |i|
(i...column_count).each do |j|
yield self[i, j]
end
end
else
raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
end
self
def each(which = :all) # :yield: e
return to_enum :each, which unless block_given?

each_with_index(which){ |elem, _, _| yield elem}
end

#
# Same as #each, but the row index and column index in addition to the element
#
Expand All @@ -179,17 +135,85 @@ def each(which = :all) # :yield: e
# # 3 at 1, 0
# # 4 at 1, 1
#
def each_with_index
raise NotSupportedError unless block_given?
def each_with_index(which = :all) # :yield: e, row, column
return to_enum :each_with_index, which unless block_given?
case which
when :all
each_all{|i, j| yield self[i, j], i, j}
when :diagonal
each_diagonal{|i, j| yield self[i, j], i, j}
when :off_diagonal
each_off_diagonal{|i, j| yield self[i, j], i, j}
when :lower
each_lower{|i, j| yield self[i, j], i, j}
when :strict_lower
each_strict_lower{|i, j| yield self[i, j], i, j}
when :strict_upper
each_strict_upper{|i, j| yield self[i, j], i, j}
when :upper
each_upper{|i, j| yield self[i, j], i, j}
else
raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
end
self
end

def each_all(&block)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This methods don't return items of the matrix -> they aren't each.
I think, that they can be extracted into a special module (may be named Utils or TraversalSequence), if row_count and column_count put in parameters.

(0...row_count).each do |i|
(0...column_count).each do |j|
yield self[i, j], i, j
block[i,j]
end
end
self
end

def each_diagonal(&block)
(0...[row_count, column_count].min).each do |i|
block[i, i]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't pass a block anywhere, you should use yield

end
end

def each_off_diagonal(&block)
(0...row_count).each do |i|
(0...column_count).each do |j|
if i != j
block[i, j]
end
end
end
end

def each_lower(&block)
(0...row_count).each do |i|
(0..[i,column_count-1].min).each do |j|
block[i, j]
end
end
end

def each_strict_lower(&block)
(1...row_count).each do |i|
(0...[i,column_count].min).each do |j|
block[i, j]
end
end
end

def each_strict_upper(&block)
(0...row_count).each do |i|
(i+1...column_count).each do |j|
block[i, j]
end
end
end

def each_upper(&block)
(0...row_count).each do |i|
(i...column_count).each do |j|
block[i, j]
end
end
end

# don't use (Issue#1)
def each_with_index!
(0...row_count).each do |i|
Expand Down
115 changes: 115 additions & 0 deletions test/matrix/matrix_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,121 @@ def test_each_strict_upper_rec2
assert_equal [2, 3, 6], m.each(:strict_upper).to_a
end

def test_each_wi_all_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 1, 0], [4.0, 1, 1]], m.each_with_index(:all).to_a
end

def test_each_wi_all_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 1, 0], [4.0, 1, 1], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:all).to_a
end

def test_each_wi_all_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 0, 2], [4.0, 1, 0], [5.0, 1, 1], [6.0, 1, 2]], m.each_with_index(:all).to_a
end

def test_each_wi_diagonal_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[1.0, 0, 0], [4.0, 1, 1]], m.each_with_index(:diagonal).to_a
end

def test_each_wi_diagonal_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[1.0, 0, 0], [4.0, 1, 1]], m.each_with_index(:diagonal).to_a
end

def test_each_wi_diagonal_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[1.0, 0, 0], [5.0, 1, 1]], m.each_with_index(:diagonal).to_a
end

def test_each_wi_off_diagonal_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[2.0, 0, 1], [3.0, 1, 0]], m.each_with_index(:off_diagonal).to_a
end

def test_each_wi_off_diagonal_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[2.0, 0, 1], [3.0, 1, 0], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:off_diagonal).to_a
end

def test_each_wi_off_diagonal_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[2.0, 0, 1], [3.0, 0, 2], [4.0, 1, 0], [6.0, 1, 2]], m.each_with_index(:off_diagonal).to_a
end

def test_each_wi_lower_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[1.0, 0, 0], [3.0, 1, 0], [4.0, 1, 1]], m.each_with_index(:lower).to_a
end

def test_each_wi_lower_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[1.0, 0, 0], [3.0, 1, 0], [4.0, 1, 1], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:lower).to_a
end

def test_each_wi_lower_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[1.0, 0, 0], [4.0, 1, 0], [5.0, 1, 1]], m.each_with_index(:lower).to_a
end

def test_each_wi_strict_lower_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[3.0, 1, 0]], m.each_with_index(:strict_lower).to_a
end

def test_each_wi_strict_lower_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[3.0, 1, 0], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:strict_lower).to_a
end

def test_each_wi_strict_lower_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[4.0, 1, 0]], m.each_with_index(:strict_lower).to_a
end

def test_each_wi_upper_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [4.0, 1, 1]], m.each_with_index(:upper).to_a
end

def test_each_wi_upper_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [4.0, 1, 1]], m.each_with_index(:upper).to_a
end

def test_each_wi_upper_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 0, 2], [5.0, 1, 1], [6.0, 1, 2]], m.each_with_index(:upper).to_a
end

def test_each_wi_strict_upper_sq
m = Matrix[[1, 2], [3, 4]]
assert_equal [[2.0, 0, 1]], m.each_with_index(:strict_upper).to_a
end

def test_each_wi_strict_upper_rec1
m = Matrix[[1, 2], [3, 4], [5, 6]]
assert_equal [[2.0, 0, 1]], m.each_with_index(:strict_upper).to_a
end

def test_each_wi_strict_upper_rec2
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_equal [[2.0, 0, 1], [3.0, 0, 2], [6.0, 1, 2]], m.each_with_index(:strict_upper).to_a
end

def test_each_argument_error
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_raises (ArgumentError){ m.each(:al).to_a }
end

def test_each_wi_argument_error
m = Matrix[[1, 2, 3], [4, 5, 6]]
assert_raises (ArgumentError){ m.each_with_index(:al).to_a }
end

def test_greater
m1 = Matrix[[1, 2, 3], [3, 2, 1]]
m2 = Matrix[[2, 3, 6], [4, 4, 4]]
Expand Down