summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS2
-rw-r--r--lib/matrix.rb31
3 files changed, 38 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 17ec828753..236cbab7ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jun 29 10:09:35 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
+
+ * lib/matrix.rb: Specialize Matrix#find_index to return [row, col]
+ and accept the same optional argument as #each
+
Wed Jun 29 10:07:32 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* lib/matrix.rb: Matrix#each{_with_index} can iterate over a subset
diff --git a/NEWS b/NEWS
index c4c9c845b5..4423c5310a 100644
--- a/NEWS
+++ b/NEWS
@@ -159,6 +159,8 @@ with all sufficient information, see the ChangeLog file.
* matrix
* extended methods:
* Matrix#each and #each_with_index can iterate on a subset of the elements
+ * Matrix#find_index returns [row, column] and can iterate on a subset
+ of the elements
* net/http
* SNI (Server Name Indication) supported for HTTPS.
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 6c037063d3..7978bb9de3 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -56,6 +56,7 @@ end
# * <tt> #map </tt>
# * <tt> #each </tt>
# * <tt> #each_with_index </tt>
+# * <tt> #find_index </tt>
# * <tt> #minor(*param) </tt>
#
# Properties of a matrix:
@@ -490,6 +491,36 @@ class Matrix
self
end
+ SELECTORS = {all: true, diagonal: true, off_diagonal: true, lower: true, strict_lower: true, strict_upper: true, upper: true}.freeze
+ #
+ # :call-seq:
+ # index(value, selector = :all) -> [row, column]
+ # index(selector = :all){ block } -> [row, column]
+ # index(selector = :all) -> an_enumerator
+ #
+ # The index method is specialized to return the index as [row, column]
+ # It also accepts an optional +selector+ argument, see #each for details.
+ #
+ # Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
+ # Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]
+ #
+ def index(*args)
+ raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
+ which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
+ return to_enum :find_index, which, *args unless block_given? || args.size == 1
+ if args.size == 1
+ value = args.first
+ each_with_index(which) do |e, row_index, col_index|
+ return row_index, col_index if e == value
+ end
+ else
+ each_with_index(which) do |e, row_index, col_index|
+ return row_index, col_index if yield e
+ end
+ end
+ nil
+ end
+ alias_method :find_index, :index
#
# Returns a section of the matrix. The parameters are either:
# * start_row, nrows, start_col, ncols; OR