diff options
Diffstat (limited to 'mrbgems/mruby-array-ext/mrblib')
| -rw-r--r-- | mrbgems/mruby-array-ext/mrblib/array.rb | 267 |
1 files changed, 95 insertions, 172 deletions
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index ed3f591fe..7520b932f 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -1,32 +1,6 @@ -# coding: cp932 class Array ## # call-seq: - # Array.try_convert(obj) -> array or nil - # - # Tries to convert +obj+ into an array, using +to_ary+ method. - # converted array or +nil+ if +obj+ cannot be converted for any reason. - # This method can be used to check if an argument is an array. - # - # Array.try_convert([1]) #=> [1] - # Array.try_convert("1") #=> nil - # - # if tmp = Array.try_convert(arg) - # # the argument is an array - # elsif tmp = String.try_convert(arg) - # # the argument is a string - # end - # - def self.try_convert(obj) - if obj.respond_to?(:to_ary) - obj.to_ary - else - nil - end - end - - ## - # call-seq: # ary.uniq! -> ary or nil # ary.uniq! { |item| ... } -> ary or nil # @@ -77,7 +51,7 @@ class Array # b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]] # def uniq(&block) - ary = self.dup + ary = self[0..-1] ary.uniq!(&block) ary end @@ -116,6 +90,22 @@ class Array ## # call-seq: + # ary.difference(other_ary1, other_ary2, ...) -> new_ary + # + # Returns a new array that is a copy of the original array, removing all + # occurrences of any item that also appear in +other_ary+. The order is + # preserved from the original array. + # + def difference(*args) + ary = self + args.each do |x| + ary = ary - x + end + ary + end + + ## + # call-seq: # ary | other_ary -> new_ary # # Set Union---Returns a new array by joining this array with @@ -160,7 +150,7 @@ class Array # [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ] # def &(elem) - raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array + raise TypeError, "cannot convert #{elem.class} into Array" unless elem.class == Array hash = {} array = [] @@ -185,6 +175,65 @@ class Array ## # call-seq: + # ary.intersection(other_ary,...) -> new_ary + # + # Set Intersection---Returns a new array containing elements common to + # this array and <i>other_ary</i>s, removing duplicates. The order is + # preserved from the original array. + # + # [1, 2, 3].intersection([3, 4, 1], [1, 3, 5]) #=> [1, 3] + # + def intersection(*args) + ary = self + args.each do |x| + ary = ary & x + end + ary + end + + ## + # call-seq: + # ary.intersect?(other_ary) -> true or false + # + # Returns +true+ if the array and +other_ary+ have at least one element in + # common, otherwise returns +false+. + # + # a = [ 1, 2, 3 ] + # b = [ 3, 4, 5 ] + # c = [ 5, 6, 7 ] + # a.intersect?(b) #=> true + # a.intersect?(c) #=> false + def intersect?(ary) + raise TypeError, "cannot convert #{ary.class} into Array" unless ary.class == Array + + hash = {} + if self.length > ary.length + shorter = ary + longer = self + else + shorter = self + longer = ary + end + idx = 0 + len = shorter.size + while idx < len + hash[shorter[idx]] = true + idx += 1 + end + idx = 0 + len = size + while idx < len + v = longer[idx] + if hash[v] + return true + end + idx += 1 + end + false + end + + ## + # call-seq: # ary.flatten -> new_ary # ary.flatten(level) -> new_ary # @@ -201,7 +250,7 @@ class Array # a.flatten(1) #=> [1, 2, 3, [4, 5]] # def flatten(depth=nil) - res = dup + res = Array.new(self) res.flatten! depth res end @@ -245,41 +294,6 @@ class Array end end - ## - # call-seq: - # ary.compact -> new_ary - # - # Returns a copy of +self+ with all +nil+ elements removed. - # - # [ "a", nil, "b", nil, "c", nil ].compact - # #=> [ "a", "b", "c" ] - # - def compact - result = self.dup - result.compact! - result - end - - ## - # call-seq: - # ary.compact! -> ary or nil - # - # Removes +nil+ elements from the array. - # Returns +nil+ if no changes were made, otherwise returns - # <i>ary</i>. - # - # [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] - # [ "a", "b", "c" ].compact! #=> nil - # - def compact! - result = self.select { |e| !e.nil? } - if result.size == self.size - nil - else - self.replace(result) - end - end - # for efficiency def reverse_each(&block) return to_enum :reverse_each unless block @@ -292,7 +306,6 @@ class Array self end - NONE=Object.new ## # call-seq: # ary.fetch(index) -> obj @@ -317,8 +330,8 @@ class Array # #=> "100 is out of bounds" # - def fetch(n=nil, ifnone=NONE, &block) - warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block + def fetch(n, ifnone=NONE, &block) + #warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block idx = n if idx < 0 @@ -373,7 +386,6 @@ class Array end beg = len = 0 - ary = [] if block if arg0.nil? && arg1.nil? && arg2.nil? # ary.fill { |index| block } -> ary @@ -437,57 +449,6 @@ class Array ## # call-seq: - # ary.rotate(count=1) -> new_ary - # - # Returns a new array by rotating +self+ so that the element at +count+ is - # the first element of the new array. - # - # If +count+ is negative then it rotates in the opposite direction, starting - # from the end of +self+ where +-1+ is the last element. - # - # a = [ "a", "b", "c", "d" ] - # a.rotate #=> ["b", "c", "d", "a"] - # a #=> ["a", "b", "c", "d"] - # a.rotate(2) #=> ["c", "d", "a", "b"] - # a.rotate(-3) #=> ["b", "c", "d", "a"] - - def rotate(count=1) - ary = [] - len = self.length - - if len > 0 - idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count - len.times do - ary << self[idx] - idx += 1 - idx = 0 if idx > len-1 - end - end - ary - end - - ## - # call-seq: - # ary.rotate!(count=1) -> ary - # - # Rotates +self+ in place so that the element at +count+ comes first, and - # returns +self+. - # - # If +count+ is negative then it rotates in the opposite direction, starting - # from the end of the array where +-1+ is the last element. - # - # a = [ "a", "b", "c", "d" ] - # a.rotate! #=> ["b", "c", "d", "a"] - # a #=> ["b", "c", "d", "a"] - # a.rotate!(2) #=> ["d", "a", "b", "c"] - # a.rotate!(-3) #=> ["a", "b", "c", "d"] - - def rotate!(count=1) - self.replace(self.rotate(count)) - end - - ## - # call-seq: # ary.delete_if { |item| block } -> ary # ary.delete_if -> Enumerator # @@ -681,37 +642,6 @@ class Array ## # call-seq: - # ary.delete_if { |item| block } -> ary - # ary.delete_if -> Enumerator - # - # Deletes every element of +self+ for which block evaluates to +true+. - # - # The array is changed instantly every time the block is called, not after - # the iteration is over. - # - # See also Array#reject! - # - # If no block is given, an Enumerator is returned instead. - # - # scores = [ 97, 42, 75 ] - # scores.delete_if {|score| score < 80 } #=> [97] - - def delete_if(&block) - return to_enum :delete_if unless block - - idx = 0 - while idx < self.size do - if block.call(self[idx]) - self.delete_at(idx) - else - idx += 1 - end - end - self - end - - ## - # call-seq: # ary.keep_if { |item| block } -> ary # ary.keep_if -> Enumerator # @@ -729,7 +659,6 @@ class Array return to_enum :keep_if unless block idx = 0 - len = self.size while idx < self.size do if block.call(self[idx]) idx += 1 @@ -799,16 +728,6 @@ class Array end ## - # call-seq: - # ary.to_ary -> ary - # - # Returns +self+. - # - def to_ary - self - end - - ## # call-seq: # ary.dig(idx, ...) -> object # @@ -852,12 +771,11 @@ class Array # a.permutation(0).to_a #=> [[]] # one permutation of length 0 # a.permutation(4).to_a #=> [] # no permutations of length 4 def permutation(n=self.size, &block) - size = self.size return to_enum(:permutation, n) unless block - return if n > size + size = self.size if n == 0 - yield [] - else + yield [] + elsif 0 < n && n <= size i = 0 while i<size result = [self[i]] @@ -872,6 +790,7 @@ class Array i += 1 end end + self end ## @@ -898,9 +817,8 @@ class Array # a.combination(5).to_a #=> [] # no combinations of length 5 def combination(n, &block) - size = self.size return to_enum(:combination, n) unless block - return if n > size + size = self.size if n == 0 yield [] elsif n == 1 @@ -909,7 +827,7 @@ class Array yield [self[i]] i += 1 end - else + elsif n <= size i = 0 while i<size result = [self[i]] @@ -919,6 +837,7 @@ class Array i += 1 end end + self end ## @@ -927,7 +846,7 @@ class Array # # Assumes that self is an array of arrays and transposes the rows and columns. # - # If the length of the subarrays don’t match, an IndexError is raised. + # If the length of the subarrays don't match, an IndexError is raised. # # Examples: # @@ -940,8 +859,8 @@ class Array column_count = nil self.each do |row| raise TypeError unless row.is_a?(Array) - column_count ||= row.count - raise IndexError, 'element size differs' unless column_count == row.count + column_count ||= row.size + raise IndexError, 'element size differs' unless column_count == row.size end Array.new(column_count) do |column_index| @@ -954,7 +873,7 @@ class Array # ary.to_h -> Hash # ary.to_h{|item| ... } -> Hash # - # Returns the result of interpreting <i>aray</i> as an array of + # Returns the result of interpreting <i>array</i> as an array of # <tt>[key, value]</tt> pairs. If a block is given, it should # return <tt>[key, value]</tt> pairs to construct a hash. # @@ -973,4 +892,8 @@ class Array end h end + + alias append push + alias prepend unshift + alias filter! select! end |
