[前][次][番号順一覧][スレッド一覧]

ruby-changes:20229

From: marcandre <ko1@a...>
Date: Wed, 29 Jun 2011 10:08:16 +0900 (JST)
Subject: [ruby-changes:20229] marcandRe: r32277 (trunk): * lib/matrix.rb: Matrix#each{_with_index} can iterate over a subset of the Matrix

marcandre	2011-06-29 10:08:02 +0900 (Wed, 29 Jun 2011)

  New Revision: 32277

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32277

  Log:
    * lib/matrix.rb: Matrix#each{_with_index} can iterate over a subset of the Matrix

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/lib/matrix.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 32276)
+++ ChangeLog	(revision 32277)
@@ -1,3 +1,8 @@
+Wed Jun 29 10:07:32 2011  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* lib/matrix.rb: Matrix#each{_with_index} can iterate over a subset
+	  of the Matrix
+
 Wed Jun 29 06:21:02 2011  Koichi Sasada  <ko1@a...>
 
 	* thread_pthread.c (native_stop_timer_thread): skip to close
Index: lib/matrix.rb
===================================================================
--- lib/matrix.rb	(revision 32276)
+++ lib/matrix.rb	(revision 32277)
@@ -365,36 +365,127 @@
 
   #
   # Yields all elements of the matrix, starting with those of the first row,
-  # or returns an Enumerator is no block given
+  # or returns an Enumerator is no block given.
+  # Elements can be restricted by passing an argument:
+  # * :all (default): yields all elements
+  # * :diagonal: yields only elements on the diagonal
+  # * :off_diagonal: yields all elements except on the diagonal
+  # * :lower: yields only elements on or below the diagonal
+  # * :strict_lower: yields only elements below the diagonal
+  # * :strict_upper: yields only elements above the diagonal
+  # * :upper: yields only elements on or above the diagonal
+  #
   #   Matrix[ [1,2], [3,4] ].each { |e| puts e }
   #     # => prints the numbers 1 to 4
+  #   Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
   #
-  def each(&block) # :yield: e
-    return to_enum(:each) unless block_given?
-    @rows.each do |row|
-      row.each(&block)
+  def each(which = :all) # :yield: e
+    return to_enum :each, which unless block_given?
+    last = column_size - 1
+    case which
+    when :all
+      block = Proc.new
+      @rows.each do |row|
+        row.each(&block)
+      end
+    when :diagonal
+      @rows.each_with_index do |row, row_index|
+        yield row.fetch(row_index){return self}
+      end
+    when :off_diagonal
+      @rows.each_with_index do |row, row_index|
+        column_size.times do |col_index|
+          yield row[col_index] unless row_index == col_index
+        end
+      end
+    when :lower
+      @rows.each_with_index do |row, row_index|
+        0.upto([row_index, last].min) do |col_index|
+          yield row[col_index]
+        end
+      end
+    when :strict_lower
+      @rows.each_with_index do |row, row_index|
+        [row_index, column_size].min.times do |col_index|
+          yield row[col_index]
+        end
+      end
+    when :strict_upper
+      @rows.each_with_index do |row, row_index|
+        (row_index+1).upto(last) do |col_index|
+          yield row[col_index]
+        end
+      end
+    when :upper
+      @rows.each_with_index do |row, row_index|
+        row_index.upto(last) do |col_index|
+          yield row[col_index]
+        end
+      end
+    else
+      Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
     end
     self
   end
 
   #
-  # Yields all elements of the matrix, starting with those of the first row,
-  # along with the row index and column index,
-  # or returns an Enumerator is no block given
+  # Same as #each, but the row index and column index in addition to the element
+  #
   #   Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
   #     puts "#{e} at #{row}, #{col}"
   #   end
-  #     # => 1 at 0, 0
-  #     # => 2 at 0, 1
-  #     # => 3 at 1, 0
-  #     # => 4 at 1, 1
+  #     # => Prints:
+  #     #    1 at 0, 0
+  #     #    2 at 0, 1
+  #     #    3 at 1, 0
+  #     #    4 at 1, 1
   #
-  def each_with_index(&block) # :yield: e, row, column
-    return to_enum(:each_with_index) unless block_given?
-    @rows.each_with_index do |row, row_index|
-      row.each_with_index do |e, col_index|
-        yield e, row_index, col_index
+  def each_with_index(which = :all) # :yield: e, row, column
+    return to_enum :each_with_index, which unless block_given?
+    last = column_size - 1
+    case which
+    when :all
+      @rows.each_with_index do |row, row_index|
+        row.each_with_index do |e, col_index|
+          yield e, row_index, col_index
+        end
       end
+    when :diagonal
+      @rows.each_with_index do |row, row_index|
+        yield row.fetch(row_index){return self}, row_index, row_index
+      end
+    when :off_diagonal
+      @rows.each_with_index do |row, row_index|
+        column_size.times do |col_index|
+          yield row[col_index], row_index, col_index unless row_index == col_index
+        end
+      end
+    when :lower
+      @rows.each_with_index do |row, row_index|
+        0.upto([row_index, last].min) do |col_index|
+          yield row[col_index], row_index, col_index
+        end
+      end
+    when :strict_lower
+      @rows.each_with_index do |row, row_index|
+        [row_index, column_size].min.times do |col_index|
+          yield row[col_index], row_index, col_index
+        end
+      end
+    when :strict_upper
+      @rows.each_with_index do |row, row_index|
+        (row_index+1).upto(last) do |col_index|
+          yield row[col_index], row_index, col_index
+        end
+      end
+    when :upper
+      @rows.each_with_index do |row, row_index|
+        row_index.upto(last) do |col_index|
+          yield row[col_index], row_index, col_index
+        end
+      end
+    else
+      Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
     end
     self
   end
Index: NEWS
===================================================================
--- NEWS	(revision 32276)
+++ NEWS	(revision 32277)
@@ -156,6 +156,10 @@
     * IO#winsize
     * IO.console
 
+* matrix
+  * extended methods:
+    * Matrix#each and #each_with_index can iterate on a subset of the elements
+
 * net/http
   * SNI (Server Name Indication) supported for HTTPS. 
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]