Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/mrblib/array.rb

    r331 r439  
    11class Array
    2   ##
    3   # call-seq:
    4   #    Array.try_convert(obj) -> array or nil
    5   #
    6   # Tries to convert +obj+ into an array, using +to_ary+ method.
    7   # converted array or +nil+ if +obj+ cannot be converted for any reason.
    8   # This method can be used to check if an argument is an array.
    9   #
    10   #    Array.try_convert([1])   #=> [1]
    11   #    Array.try_convert("1")   #=> nil
    12   #
    13   #    if tmp = Array.try_convert(arg)
    14   #      # the argument is an array
    15   #    elsif tmp = String.try_convert(arg)
    16   #      # the argument is a string
    17   #    end
    18   #
    19   def self.try_convert(obj)
    20     if obj.respond_to?(:to_ary)
    21       obj.to_ary
    22     else
    23       nil
    24     end
    25   end
    26 
    272  ##
    283  # call-seq:
     
    4217  #
    4318  def uniq!(&block)
    44     ary = self.dup
    45     result = []
     19    hash = {}
    4620    if block
     21      self.each do |val|
     22        key = block.call(val)
     23        hash[key] = val unless hash.key?(key)
     24      end
     25      result = hash.values
     26    else
    4727      hash = {}
    48       while ary.size > 0
    49         val = ary.shift
    50         key = block.call(val)
    51         hash[key] = val unless hash.has_key?(key)
    52       end
    53       hash.each_value do |value|
    54         result << value
    55       end
    56     else
    57       while ary.size > 0
    58         result << ary.shift
    59         ary.delete(result.last)
    60       end
     28      self.each do |val|
     29        hash[val] = val
     30      end
     31      result = hash.keys
    6132    end
    6233    if result.size == self.size
     
    8253  def uniq(&block)
    8354    ary = self.dup
    84     if block
    85       ary.uniq!(&block)
    86     else
    87       ary.uniq!
    88     end
     55    ary.uniq!(&block)
    8956    ary
    9057  end
     
    10673    hash = {}
    10774    array = []
    108     elem.each { |x| hash[x] = true }
    109     self.each { |x| array << x unless hash[x] }
     75    idx = 0
     76    len = elem.size
     77    while idx < len
     78      hash[elem[idx]] = true
     79      idx += 1
     80    end
     81    idx = 0
     82    len = size
     83    while idx < len
     84      v = self[idx]
     85      array << v unless hash[v]
     86      idx += 1
     87    end
    11088    array
     89  end
     90
     91  ##
     92  # call-seq:
     93  #    ary.difference(other_ary1, other_ary2, ...)   -> new_ary
     94  #
     95  # Returns a new array that is a copy of the original array, removing all
     96  # occurrences of any item that also appear in +other_ary+. The order is
     97  # preserved from the original array.
     98  #
     99  def difference(*args)
     100    ary = self
     101    args.each do |x|
     102      ary = ary - x
     103    end
     104    ary
    111105  end
    112106
     
    130124  ##
    131125  # call-seq:
     126  #    ary.union(other_ary,...)  -> new_ary
     127  #
     128  # Set Union---Returns a new array by joining this array with
     129  # <i>other_ary</i>, removing duplicates.
     130  #
     131  #    ["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"])
     132  #           #=> ["a", "b", "c", "d", "e"]
     133  #
     134  def union(*args)
     135    ary = self.dup
     136    args.each do |x|
     137      ary.concat(x)
     138      ary.uniq!
     139    end
     140    ary
     141  end
     142
     143  ##
     144  # call-seq:
    132145  #    ary & other_ary      -> new_ary
    133146  #
     
    142155    hash = {}
    143156    array = []
    144     elem.each{|v| hash[v] = true }
    145     self.each do |v|
     157    idx = 0
     158    len = elem.size
     159    while idx < len
     160      hash[elem[idx]] = true
     161      idx += 1
     162    end
     163    idx = 0
     164    len = size
     165    while idx < len
     166      v = self[idx]
    146167      if hash[v]
    147168        array << v
    148169        hash.delete v
    149170      end
     171      idx += 1
    150172    end
    151173    array
     174  end
     175
     176  ##
     177  # call-seq:
     178  #    ary.intersection(other_ary,...)  -> new_ary
     179  #
     180  # Set Intersection---Returns a new array containing elements common to
     181  # this array and <i>other_ary</i>s, removing duplicates. The order is
     182  # preserved from the original array.
     183  #
     184  #    [1, 2, 3].intersection([3, 4, 1], [1, 3, 5])  #=> [1, 3]
     185  #
     186  def intersection(*args)
     187    ary = self
     188    args.each do |x|
     189      ary = ary & x
     190    end
     191    ary
    152192  end
    153193
     
    170210  #
    171211  def flatten(depth=nil)
    172     ar = []
    173     self.each do |e|
    174       if e.is_a?(Array) && (depth.nil? || depth > 0)
    175         ar += e.flatten(depth.nil? ? nil : depth - 1)
    176       else
    177         ar << e
    178       end
    179     end
    180     ar
     212    res = dup
     213    res.flatten! depth
     214    res
    181215  end
    182216
     
    201235    modified = false
    202236    ar = []
    203     self.each do |e|
     237    idx = 0
     238    len = size
     239    while idx < len
     240      e = self[idx]
    204241      if e.is_a?(Array) && (depth.nil? || depth > 0)
    205242        ar += e.flatten(depth.nil? ? nil : depth - 1)
     
    208245        ar << e
    209246      end
     247      idx += 1
    210248    end
    211249    if modified
     
    253291  # for efficiency
    254292  def reverse_each(&block)
    255     return to_enum :reverse_each unless block_given?
     293    return to_enum :reverse_each unless block
    256294
    257295    i = self.size - 1
     
    263301  end
    264302
    265   NONE=Object.new
    266303  ##
    267304  #  call-seq:
     
    288325  #
    289326
    290   def fetch(n=nil, ifnone=NONE, &block)
     327  def fetch(n, ifnone=NONE, &block)
    291328    warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
    292329
     
    475512
    476513  def delete_if(&block)
    477     return to_enum :delete_if unless block_given?
     514    return to_enum :delete_if unless block
    478515
    479516    idx = 0
     
    504541
    505542  def reject!(&block)
    506     return to_enum :reject! unless block_given?
     543    return to_enum :reject! unless block
    507544
    508545    len = self.size
     
    594631
    595632  def bsearch(&block)
    596     return to_enum :bsearch unless block_given?
     633    return to_enum :bsearch unless block
     634
     635    if idx = bsearch_index(&block)
     636      self[idx]
     637    else
     638      nil
     639    end
     640  end
     641
     642  ##
     643  #  call-seq:
     644  #     ary.bsearch_index {|x| block }  -> int or nil
     645  #
     646  #  By using binary search, finds an index of a value from this array which
     647  #  meets the given condition in O(log n) where n is the size of the array.
     648  #
     649  #  It supports two modes, depending on the nature of the block and they are
     650  #  exactly the same as in the case of #bsearch method with the only difference
     651  #  being that this method returns the index of the element instead of the
     652  #  element itself. For more details consult the documentation for #bsearch.
     653
     654  def bsearch_index(&block)
     655    return to_enum :bsearch_index unless block
    597656
    598657    low = 0
    599     high = self.size
     658    high = size
    600659    satisfied = false
     660
    601661    while low < high
    602       mid = low + ((high - low) / 2).truncate
    603       val = self[mid]
    604       v = block.call(val)
    605       if v.is_a?(Integer)
    606         return val if v == 0
    607         smaller = v < 0
    608       elsif v == true
     662      mid = ((low+high)/2).truncate
     663      res = block.call self[mid]
     664
     665      case res
     666      when 0 # find-any mode: Found!
     667        return mid
     668      when Numeric # find-any mode: Continue...
     669        in_lower_half = res < 0
     670      when true # find-min mode
     671        in_lower_half = true
    609672        satisfied = true
    610         smaller = true
    611       elsif v == false || v.nil?
    612         smaller = false
    613       end
    614       if smaller
     673      when false, nil # find-min mode
     674        in_lower_half = false
     675      else
     676        raise TypeError, 'invalid block result (must be numeric, true, false or nil)'
     677      end
     678
     679      if in_lower_half
    615680        high = mid
    616681      else
     
    618683      end
    619684    end
    620     return nil if low == self.size
    621     return nil unless satisfied
    622     self[low]
    623   end
    624 
    625   ##
    626   #  call-seq:
    627   #     ary.delete_if { |item| block }  -> ary
    628   #     ary.delete_if                   -> Enumerator
    629   #
    630   #  Deletes every element of +self+ for which block evaluates to +true+.
    631   #
    632   #  The array is changed instantly every time the block is called, not after
    633   #  the iteration is over.
    634   #
    635   #  See also Array#reject!
    636   #
    637   #  If no block is given, an Enumerator is returned instead.
    638   #
    639   #     scores = [ 97, 42, 75 ]
    640   #     scores.delete_if {|score| score < 80 }   #=> [97]
    641 
    642   def delete_if(&block)
    643     return to_enum :delete_if unless block_given?
    644 
    645     idx = 0
    646     while idx < self.size do
    647       if block.call(self[idx])
    648         self.delete_at(idx)
    649       else
    650         idx += 1
    651       end
    652     end
    653     self
     685
     686    satisfied ? low : nil
    654687  end
    655688
     
    670703
    671704  def keep_if(&block)
    672     return to_enum :keep_if unless block_given?
     705    return to_enum :keep_if unless block
    673706
    674707    idx = 0
     
    699732
    700733  def select!(&block)
    701     return to_enum :select! unless block_given?
     734    return to_enum :select! unless block
    702735
    703736    result = []
    704     self.each do |x|
    705       result << x if block.call(x)
    706     end
    707     return nil if self.size == result.size
     737    idx = 0
     738    len = size
     739    while idx < len
     740      elem = self[idx]
     741      result << elem if block.call(elem)
     742      idx += 1
     743    end
     744    return nil if len == result.size
    708745    self.replace(result)
    709746  end
     
    727764    if block
    728765      idx = 0
    729       self.each do |*e|
    730         return idx if block.call(*e)
     766      len = size
     767      while idx < len
     768        return idx if block.call self[idx]
    731769        idx += 1
    732770      end
     
    735773    end
    736774    nil
    737   end
    738 
    739   ##
    740   #  call-seq:
    741   #     ary.to_ary -> ary
    742   #
    743   #  Returns +self+.
    744   #
    745   def to_ary
    746     self
    747775  end
    748776
     
    763791    end
    764792  end
     793
     794  ##
     795  # call-seq:
     796  #    ary.permutation { |p| block }          -> ary
     797  #    ary.permutation                        -> Enumerator
     798  #    ary.permutation(n) { |p| block }       -> ary
     799  #    ary.permutation(n)                     -> Enumerator
     800  #
     801  # When invoked with a block, yield all permutations of length +n+ of the
     802  # elements of the array, then return the array itself.
     803  #
     804  # If +n+ is not specified, yield all permutations of all elements.
     805  #
     806  # The implementation makes no guarantees about the order in which the
     807  # permutations are yielded.
     808  #
     809  # If no block is given, an Enumerator is returned instead.
     810  #
     811  # Examples:
     812  #
     813  #  a = [1, 2, 3]
     814  #  a.permutation.to_a    #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
     815  #  a.permutation(1).to_a #=> [[1],[2],[3]]
     816  #  a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
     817  #  a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
     818  #  a.permutation(0).to_a #=> [[]] # one permutation of length 0
     819  #  a.permutation(4).to_a #=> []   # no permutations of length 4
     820  def permutation(n=self.size, &block)
     821    return to_enum(:permutation, n) unless block
     822    size = self.size
     823    if n == 0
     824      yield []
     825    elsif 0 < n && n <= size
     826      i = 0
     827      while i<size
     828        result = [self[i]]
     829        if n-1 > 0
     830          ary = self[0...i] + self[i+1..-1]
     831          ary.permutation(n-1) do |c|
     832            yield result + c
     833          end
     834        else
     835          yield result
     836        end
     837        i += 1
     838      end
     839    end
     840    self
     841  end
     842
     843  ##
     844  # call-seq:
     845  #    ary.combination(n) { |c| block }    -> ary
     846  #    ary.combination(n)                  -> Enumerator
     847  #
     848  # When invoked with a block, yields all combinations of length +n+ of elements
     849  # from the array and then returns the array itself.
     850  #
     851  # The implementation makes no guarantees about the order in which the
     852  # combinations are yielded.
     853  #
     854  # If no block is given, an Enumerator is returned instead.
     855  #
     856  # Examples:
     857  #
     858  #    a = [1, 2, 3, 4]
     859  #    a.combination(1).to_a  #=> [[1],[2],[3],[4]]
     860  #    a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
     861  #    a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
     862  #    a.combination(4).to_a  #=> [[1,2,3,4]]
     863  #    a.combination(0).to_a  #=> [[]] # one combination of length 0
     864  #    a.combination(5).to_a  #=> []   # no combinations of length 5
     865
     866  def combination(n, &block)
     867    return to_enum(:combination, n) unless block
     868    size = self.size
     869    if n == 0
     870       yield []
     871    elsif n == 1
     872      i = 0
     873      while i<size
     874        yield [self[i]]
     875        i += 1
     876      end
     877    elsif n <= size
     878      i = 0
     879      while i<size
     880        result = [self[i]]
     881        self[i+1..-1].combination(n-1) do |c|
     882          yield result + c
     883        end
     884        i += 1
     885      end
     886    end
     887    self
     888  end
     889
     890  ##
     891  # call-seq:
     892  #    ary.transpose -> new_ary
     893  #
     894  # Assumes that self is an array of arrays and transposes the rows and columns.
     895  #
     896  # If the length of the subarrays don't match, an IndexError is raised.
     897  #
     898  # Examples:
     899  #
     900  #    a = [[1,2], [3,4], [5,6]]
     901  #    a.transpose   #=> [[1, 3, 5], [2, 4, 6]]
     902
     903  def transpose
     904    return [] if empty?
     905
     906    column_count = nil
     907    self.each do |row|
     908      raise TypeError unless row.is_a?(Array)
     909      column_count ||= row.size
     910      raise IndexError, 'element size differs' unless column_count == row.size
     911    end
     912
     913    Array.new(column_count) do |column_index|
     914      self.map { |row| row[column_index] }
     915    end
     916  end
     917
     918  ##
     919  #  call-seq:
     920  #    ary.to_h                ->   Hash
     921  #    ary.to_h{|item| ... }   ->   Hash
     922  #
     923  # Returns the result of interpreting <i>aray</i> as an array of
     924  # <tt>[key, value]</tt> pairs. If a block is given, it should
     925  # return <tt>[key, value]</tt> pairs to construct a hash.
     926  #
     927  #     [[:foo, :bar], [1, 2]].to_h
     928  #       # => {:foo => :bar, 1 => 2}
     929  #     [1, 2].to_h{|x| [x, x*2]}
     930  #       # => {1 => 2, 2 => 4}
     931  #
     932  def to_h(&blk)
     933    h = {}
     934    self.each do |v|
     935      v = blk.call(v) if blk
     936      raise TypeError, "wrong element type #{v.class}" unless Array === v
     937      raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2
     938      h[v[0]] = v[1]
     939    end
     940    h
     941  end
     942
     943  alias append push
     944  alias prepend unshift
     945  alias filter! select!
    765946end
Note: See TracChangeset for help on using the changeset viewer.