summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-array-ext/mrblib/array.rb
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-11-04 15:54:09 +0900
committerGitHub <[email protected]>2021-11-04 15:54:09 +0900
commit8f67a0d0e1c6c05a82645917ee3e1c0dbcd6e0b4 (patch)
treea3fe8bbd974100e787ada69a6eb66cf584b7b07d /mrbgems/mruby-array-ext/mrblib/array.rb
parentb940ed69d9acc51ed06c3e97364d94253f41e378 (diff)
parent5ea26260fa0e178537199c7fd608dd3e1e1eafdb (diff)
downloadmruby-8f67a0d0e1c6c05a82645917ee3e1c0dbcd6e0b4.tar.gz
mruby-8f67a0d0e1c6c05a82645917ee3e1c0dbcd6e0b4.zip
Merge pull request #5569 from dearblue/array-product
Added `Array#product` method
Diffstat (limited to 'mrbgems/mruby-array-ext/mrblib/array.rb')
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb47
1 files changed, 47 insertions, 0 deletions
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb
index 7520b932f..f7576cbf7 100644
--- a/mrbgems/mruby-array-ext/mrblib/array.rb
+++ b/mrbgems/mruby-array-ext/mrblib/array.rb
@@ -896,4 +896,51 @@ class Array
alias append push
alias prepend unshift
alias filter! select!
+
+ ##
+ # call-seq:
+ # ary.product(*arys) -> array
+ # ary.product(*arys) { |item| ... } -> self
+ def product(*arys, &block)
+ size = arys.size
+ i = size
+ while i > 0
+ i -= 1
+ unless arys[i].kind_of?(Array)
+ raise TypeError, "no implicit conversion into Array"
+ end
+ end
+
+ i = size
+ total = self.size
+ total *= arys[i -= 1].size while i > 0
+
+ if block
+ result = self
+ list = ->(*, e) { block.call e }
+ class << list; alias []= call; end
+ else
+ result = [nil] * total
+ list = result
+ end
+
+ i = 0
+ while i < total
+ group = [nil] * (size + 1)
+ j = size
+ n = i
+ while j > 0
+ j -= 1
+ a = arys[j]
+ b = a.size
+ group[j + 1] = a[n % b]
+ n /= b
+ end
+ group[0] = self[n]
+ list[i] = group
+ i += 1
+ end
+
+ result
+ end
end