Class: Array

Inherits:
Object show all
Defined in:
lib/backports/rails/array.rb,
lib/backports/1.8.7/array/pop.rb,
lib/backports/2.3.0/array/dig.rb,
lib/backports/1.9.2/array/uniq.rb,
lib/backports/1.9.2/array/uniq.rb,
lib/backports/2.6.0/array/to_h.rb,
lib/backports/1.8.7/array/cycle.rb,
lib/backports/1.8.7/array/index.rb,
lib/backports/1.8.7/array/shift.rb,
lib/backports/2.6.0/array/union.rb,
lib/backports/1.8.7/array/rindex.rb,
lib/backports/1.9.1/array/sample.rb,
lib/backports/1.9.2/array/rotate.rb,
lib/backports/1.9.2/array/rotate.rb,
lib/backports/1.9.2/array/select.rb,
lib/backports/2.5.0/array/append.rb,
lib/backports/1.8.7/array/flatten.rb,
lib/backports/1.8.7/array/product.rb,
lib/backports/1.8.7/array/shuffle.rb,
lib/backports/1.9.2/array/keep_if.rb,
lib/backports/1.9.2/array/product.rb,
lib/backports/1.9.2/array/sort_by.rb,
lib/backports/2.0.0/array/bsearch.rb,
lib/backports/2.5.0/array/prepend.rb,
lib/backports/2.5.0/enumerable/any.rb,
lib/backports/3.1.0/array/intersect.rb,
lib/backports/2.6.0/array/difference.rb,
lib/backports/1.8.7/array/combination.rb,
lib/backports/1.8.7/array/permutation.rb,
lib/backports/2.7.0/array/intersection.rb,
lib/backports/2.3.0/array/bsearch_index.rb,
lib/backports/1.9.2/array/repeated_combination.rb,
lib/backports/1.9.2/array/repeated_permutation.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.try_convert(obj) ⇒ Object



4
5
6
# File 'lib/backports/1.9.1/array/try_convert.rb', line 4

def Array.try_convert(obj)
  Backports.try_convert(obj, Array, :to_ary)
end

Instance Method Details

#any_with_pattern?(pattern = Backports::Undefined, &block) ⇒ Boolean

Returns:

  • (Boolean)


21
22
23
24
25
# File 'lib/backports/2.5.0/enumerable/any.rb', line 21

def any_with_pattern?(pattern = Backports::Undefined, &block)
  return any_without_pattern?(&block) if Backports::Undefined == pattern
  each_entry { |x| return true if pattern === x }
  false
end

#bsearchObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/backports/2.0.0/array/bsearch.rb', line 3

def bsearch
  return to_enum(__method__) unless block_given?
  from = 0
  to   = size - 1
  satisfied = nil
  while from <= to do
    midpoint = (from + to).div(2)
    result = yield(cur = self[midpoint])
    case result
    when Numeric
      return cur if result == 0
      result = result < 0
    when true
      satisfied = cur
    when nil, false
      # nothing to do
    else
      raise TypeError, "wrong argument type #{result.class} (must be numeric, true, false or nil)"
    end

    if result
      to = midpoint - 1
    else
      from = midpoint + 1
    end
  end
  satisfied
end

#bsearch_indexObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/backports/2.3.0/array/bsearch_index.rb', line 3

def bsearch_index
  return to_enum(__method__) unless block_given?
  from = 0
  to   = size - 1
  satisfied = nil
  while from <= to
    midpoint = (from + to).div(2)
    result = yield(self[midpoint])
    case result
    when Numeric
      return midpoint if result == 0
      result = result < 0
    when true
      satisfied = midpoint
    when nil, false
      # nothing to do
    else
      raise TypeError, "wrong argument type #{result.class} (must be numeric, true, false or nil)"
    end

    if result
      to = midpoint - 1
    else
      from = midpoint + 1
    end
  end
  satisfied
end

#combination(num) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/backports/1.8.7/array/combination.rb', line 6

def combination(num)
  num = Backports.coerce_to_int(num)
  return to_enum(:combination, num) unless block_given?
  return self unless (0..size).include? num
  # Implementation note: slightly tricky.
                                           # Example: self = 1..7, num = 3
  picks = (0...num).to_a                   # picks start at 0, 1, 2
  max_index = ((size-num)...size).to_a           # max (index for a given pick) is [4, 5, 6]
  pick_max_pairs = picks.zip(max_index).reverse  # pick_max_pairs = [[2, 6], [1, 5], [0, 4]]
  leave = Proc.new{return self}
  loop do
    yield values_at(*picks)
    move = pick_max_pairs.find(leave){|pick, max| picks[pick] < max}.first
    new_index = picks[move] + 1
    picks[move...num] = (new_index...(new_index+num-move)).to_a
  end
end

#cycle(n = nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
# File 'lib/backports/1.8.7/array/cycle.rb', line 5

def cycle(n = nil)
  return to_enum(:cycle, n) unless block_given?
  if n.nil?
    each{|e| yield e } until false
  else
    n = Backports.coerce_to_int(n)
    n.times{each{|e| yield e }}
  end
  nil
end

#difference(*arrays) ⇒ Object



5
6
7
# File 'lib/backports/2.6.0/array/difference.rb', line 5

def difference(*arrays)
  arrays.inject(Array.new(self), :-)
end

#dig(index, *rest) ⇒ Object

Raises:

  • (TypeError)


3
4
5
6
7
8
# File 'lib/backports/2.3.0/array/dig.rb', line 3

def dig(index, *rest)
  val = self[index]
  return val if rest.empty? || val == nil
  raise TypeError, "#{val.class} does not have #dig method" unless val.respond_to? :dig
  val.dig(*rest)
end

#extract_options!Object

See official documentation



7
8
9
# File 'lib/backports/rails/array.rb', line 7

def extract_options!
  last.is_a?(::Hash) ? pop : {}
end

#flatten_with_optional_argument(level = -1)) ⇒ Object

Recursively flatten any contained Arrays into an one-dimensional result. Adapted from rubinius’



8
9
10
# File 'lib/backports/1.8.7/array/flatten.rb', line 8

def flatten_with_optional_argument(level=-1)
  dup.flatten!(level) || self
end

#flatten_with_optional_argument!(level = -1)) ⇒ Object

Flattens self in place as #flatten. If no changes are made, returns nil, otherwise self. Adapted from rubinius’



15
16
17
18
19
20
21
22
23
# File 'lib/backports/1.8.7/array/flatten.rb', line 15

def flatten_with_optional_argument!(level=-1)
  level = Backports.coerce_to_int(level)
  return flatten_without_optional_argument! if level < 0

  out = []
  ret = recursively_flatten_finite(self, out, level)
  replace(out) if ret
  ret
end

#index_with_block(*arg) ⇒ Object



6
7
8
9
10
11
# File 'lib/backports/1.8.7/array/index.rb', line 6

def index_with_block(*arg)
  return to_enum(:index_with_block) if arg.empty? && !block_given?
  return index_without_block(*arg) unless block_given? && arg.empty?
  each_with_index{|o,i| return i if yield o}
  return nil
end

#intersect?(array) ⇒ Boolean

Returns:

  • (Boolean)


5
6
7
8
9
10
11
12
13
14
# File 'lib/backports/3.1.0/array/intersect.rb', line 5

def intersect?(array)
  array = Backports.coerce_to_ary(array)

  if size < array.size
    smaller = self
  else
    smaller, array = array, self
  end
  (array & smaller).size > 0
end

#intersection(*arrays) ⇒ Object



4
5
6
# File 'lib/backports/2.7.0/array/intersection.rb', line 4

def intersection(*arrays)
  arrays.inject(Array.new(self), :&)
end

#keep_ifObject



3
4
5
6
# File 'lib/backports/1.9.2/array/keep_if.rb', line 3

def keep_if
  return to_enum(:keep_if) unless block_given?
  delete_if{|elem| !yield elem}
end

#permutation(num = Backports::Undefined) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/backports/1.8.7/array/permutation.rb', line 6

def permutation(num = Backports::Undefined)
  return to_enum(:permutation, num) unless block_given?
  num = num.equal?(Backports::Undefined) ?
        size :
        Backports.coerce_to_int(num)
  return self unless (0..size).include? num

  final_lambda = lambda do |partial, remain|
    yield partial
  end

  outer_lambda = (1..num).inject(final_lambda) do |proc, _|
    lambda do |partial, remain|
      remain.each_with_index do |val, i|
        new_remain = remain.dup
        new_remain.delete_at(i)
        proc.call(partial.dup << val, new_remain)
      end
    end
  end

  outer_lambda.call([], dup)
end

#pop_with_optional_argument(n = Backports::Undefined) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
10
11
12
13
# File 'lib/backports/1.8.7/array/pop.rb', line 6

def pop_with_optional_argument(n = Backports::Undefined)
  return pop_without_optional_argument if n == Backports::Undefined
  n = Backports.coerce_to_int(n)
  raise ArgumentError, "negative array size" if n < 0
  first = size - n
  first = 0 if first < 0
  slice!(first..size).to_a
end

#product(*arg) ⇒ Object

Raises:

  • (RangeError)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/backports/1.8.7/array/product.rb', line 5

def product(*arg)
  # Implementation notes: We build a block that will generate all the combinations
  # by building it up successively using "inject" and starting with one
  # responsible to append the values.
  #
  result = []

  arg.map!{|ary| Backports.coerce_to_ary(ary)}
  n = arg.inject(size) { |p, a| p * a.size }
  return [] if n == 0
  raise RangeError, "too big a product" if n > 1<<31
  arg.reverse! # to get the results in the same order as in MRI, vary the last argument first
  arg.push self

  outer_lambda = arg.inject(result.method(:push)) do |proc, values|
    lambda do |partial|
      values.each do |val|
        proc.call(partial.dup << val)
      end
    end
  end

  outer_lambda.call([])

  result
end

#product_with_block(*arg, &block) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/backports/1.9.2/array/product.rb', line 7

def product_with_block(*arg, &block)
  return product_without_block(*arg) unless block_given?
  # Same implementation as 1.8.7, but yielding
  arg.map!{|ary| Backports.coerce_to_ary(ary)}
  arg.reverse! # to get the results in the same order as in MRI, vary the last argument first
  arg.push self

  outer_lambda = arg.inject(block) do |proc, values|
    lambda do |partial|
      values.each do |val|
        proc.call(partial.dup << val)
      end
    end
  end

  outer_lambda.call([])
  self
end

#repeated_combination(num) ⇒ Object

Note: Combinations are not yielded in the same order as MRI. This is not a bug; the spec states that the order is implementation dependent



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/backports/1.9.2/array/repeated_combination.rb', line 8

def repeated_combination(num)
  return to_enum(:repeated_combination, num) unless block_given?
  num = Backports.coerce_to_int(num)
  if num <= 0
    yield [] if num == 0
  else
    copy = dup
    indices = Array.new(num, 0)
    indices[-1] = size
    while dec = indices.index{|x| x != 0}
      indices.fill indices[dec]-1, 0, dec + 1
      yield copy.values_at(*indices)
    end
  end
  self
end

#repeated_permutation(num) ⇒ Object

Note: Permutations are not yielded in the same order as MRI. This is not a bug; the spec states that the order is implementation dependent!!!



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/backports/1.9.2/array/repeated_permutation.rb', line 8

def repeated_permutation(num)
  return to_enum(:repeated_permutation, num) unless block_given?
  num = Backports.coerce_to_int(num)
  if num <= 0
    yield [] if num == 0
  else
    copy = dup
    indices = Array.new(num, 0)
    indices[-1] = size
    while dec = indices.index{|x| x != 0}
      indices.fill size-1, 0, dec
      indices[dec] -= 1
      yield copy.values_at(*indices)
    end
  end
  self
end

#rindex_with_block(*arg) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/backports/1.8.7/array/rindex.rb', line 6

def rindex_with_block(*arg)
  return to_enum(:rindex) if !block_given? && arg.empty?
  return rindex_without_block(*arg) unless block_given? && arg.empty?
  i = 0
  reverse_each{|o| i += 1; return size - i if yield o}
  return nil
end

#rotate(n = 1) ⇒ Object



3
4
5
# File 'lib/backports/1.9.2/array/rotate.rb', line 3

def rotate(n=1)
  Array.new(self).rotate!(n)
end

#rotate!(n = 1) ⇒ Object



12
13
14
15
# File 'lib/backports/1.9.2/array/rotate.rb', line 12

def rotate!(n=1)
  n = Backports.coerce_to_int(n) % (empty? ? 1 : size)
  concat(slice!(0, n))
end

#sample(n = Backports::Undefined, options = Backports::Undefined) ⇒ Object

Raises:

  • (ArgumentError)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/backports/1.9.1/array/sample.rb', line 5

def sample(n = Backports::Undefined, options = Backports::Undefined)
  if options == Backports::Undefined && n.respond_to?(:to_hash)
    n, options = options, n
  end
  rng = Backports.coerce_to_option(options, :random) unless options == Backports::Undefined
  generator = if rng.respond_to? :rand
    Proc.new do |nb|
      r = Backports::coerce_to_int(rng.rand(nb))
      raise RangeError, "random generator returned #{r} which is not in 0...#{nb}" if r < 0 || r >= nb
      r
    end
  else
    Kernel.method(:rand)
  end
  return self[generator.call(size)] if n == Backports::Undefined
  n = Backports.coerce_to_int(n)
  raise ArgumentError, "negative array size" if n < 0
  n = size if n > size
  result = Array.new(self)
  n.times do |i|
    r = i + generator.call(size - i)
    result[i], result[r] = result[r], result[i]
  end
  result[n..size] = []
  result
end

#select!Object



3
4
5
6
# File 'lib/backports/1.9.2/array/select.rb', line 3

def select!
  return to_enum(:select!) unless block_given?
  reject!{|elem| ! yield elem}
end

#shift_with_optional_argument(n = Backports::Undefined) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
10
11
# File 'lib/backports/1.8.7/array/shift.rb', line 6

def shift_with_optional_argument(n = Backports::Undefined)
  return shift_without_optional_argument if n == Backports::Undefined
  n = Backports.coerce_to_int(n)
  raise ArgumentError, "negative array size" if n < 0
  slice!(0, n)
end

#shuffleObject



3
4
5
# File 'lib/backports/1.8.7/array/shuffle.rb', line 3

def shuffle
  dup.shuffle!
end

#shuffle!Object

Standard in Ruby 1.8.7+. See official documentation

Raises:

  • (TypeError)


8
9
10
11
12
13
14
15
# File 'lib/backports/1.8.7/array/shuffle.rb', line 8

def shuffle!
  raise TypeError, "can't modify frozen array" if frozen?
  size.times do |i|
    r = i + Kernel.rand(size - i)
    self[i], self[r] = self[r], self[i]
  end
  self
end

#sort_by!Object



3
4
5
6
7
# File 'lib/backports/1.9.2/array/sort_by.rb', line 3

def sort_by!
  return to_enum(:sort_by!) unless block_given?
  raise "can't modify frozen array" if frozen?
  replace sort_by{|e| yield e}
end

#to_h_with_block(&block) ⇒ Object



7
8
9
10
# File 'lib/backports/2.6.0/array/to_h.rb', line 7

def to_h_with_block(&block)
  receiver = block ? map(&block) : self
  receiver.to_h_without_block
end

#union(*arrays) ⇒ Object



2
3
4
# File 'lib/backports/2.6.0/array/union.rb', line 2

def union(*arrays)
  [self, *arrays].inject([], :|)
end

#uniq_with_blockObject



5
6
7
8
9
10
11
12
13
# File 'lib/backports/1.9.2/array/uniq.rb', line 5

def uniq_with_block
  return uniq_without_block unless block_given?
  h = {}
  each do |elem|
    key = yield(elem)
    h[key] = elem unless h.has_key?(key)
  end
  h.values
end

#uniq_with_block!Object



22
23
24
25
26
27
# File 'lib/backports/1.9.2/array/uniq.rb', line 22

def uniq_with_block!
  replace self if frozen? # force error
  return uniq_without_block! unless block_given?
  u = uniq{|e| yield e}
  replace u unless u.size == size
end