Method: Array#values_at

Defined in:
array.c

#values_at(*specifiers) ⇒ Object

Returns elements from self in a new array; does not modify self.

The objects included in the returned array are the elements of self selected by the given specifiers, each of which must be a numeric index or a Range.

In brief:

a = ['a', 'b', 'c', 'd']

# Index specifiers.
a.values_at(2, 0, 2, 0)     # => ["c", "a", "c", "a"] # May repeat.
a.values_at(-4, -3, -2, -1) # => ["a", "b", "c", "d"] # Counts backwards if negative.
a.values_at(-50, 50)        # => [nil, nil]           # Outside of self.

# Range specifiers.
a.values_at(1..3)       # => ["b", "c", "d"] # From range.begin to range.end.
a.values_at(1...3)      # => ["b", "c"]      # End excluded.
a.values_at(3..1)       # => []              # No such elements.

a.values_at(-3..3)  # => ["b", "c", "d"]     # Negative range.begin counts backwards.
a.values_at(-50..3)                          # Raises RangeError.

a.values_at(1..-2)  # => ["b", "c"]          # Negative range.end counts backwards.
a.values_at(1..-50) # => []                  # No such elements.

# Mixture of specifiers.
a.values_at(2..3, 3, 0..1, 0) # => ["c", "d", "d", "a", "b", "a"]

With no specifiers given, returns a new empty array:

a = ['a', 'b', 'c', 'd']
a.values_at # => []

For each numeric specifier index, includes an element:

  • For each non-negative numeric specifier index that is in-range (less than self.size), includes the element at offset index:

    a.values_at(0, 2)     # => ["a", "c"]
    a.values_at(0.1, 2.9) # => ["a", "c"]
    
  • For each negative numeric index that is in-range (greater than or equal to - self.size), counts backwards from the end of self:

    a.values_at(-1, -4) # => ["d", "a"]
    

The given indexes may be in any order, and may repeat:

a.values_at(2, 0, 1, 0, 2) # => ["c", "a", "b", "a", "c"]

For each index that is out-of-range, includes nil:

a.values_at(4, -5) # => [nil, nil]

For each Range specifier range, includes elements according to range.begin and range.end:

  • If both range.begin and range.end are non-negative and in-range (less than self.size), includes elements from index range.begin through range.end - 1 (if range.exclude_end?), or through range.end (otherwise):

    a.values_at(1..2)  # => ["b", "c"]
    a.values_at(1...2) # => ["b"]
    
  • If range.begin is negative and in-range (greater than or equal to - self.size), counts backwards from the end of self:

    a.values_at(-2..3) # => ["c", "d"]
    
  • If range.begin is negative and out-of-range, raises an exception:

    a.values_at(-5..3) # Raises RangeError.
    
  • If range.end is positive and out-of-range, extends the returned array with nil elements:

    a.values_at(1..5) # => ["b", "c", "d", nil, nil]
    
  • If range.end is negative and in-range, counts backwards from the end of self:

    a.values_at(1..-2) # => ["b", "c"]
    
  • If range.end is negative and out-of-range, returns an empty array:

    a.values_at(1..-5) # => []
    

The given ranges may be in any order and may repeat:

a.values_at(2..3, 0..1, 2..3) # => ["c", "d", "a", "b", "c", "d"]

The given specifiers may be any mixture of indexes and ranges:

a.values_at(3, 1..2, 0, 2..3) # => ["d", "b", "c", "a", "c", "d"]

Related: see Methods for Fetching.



3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
# File 'array.c', line 3844

static VALUE
rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
{
    long i, olen = RARRAY_LEN(ary);
    VALUE result = rb_ary_new_capa(argc);
    for (i = 0; i < argc; ++i) {
        append_values_at_single(result, ary, olen, argv[i]);
    }
    RB_GC_GUARD(ary);
    return result;
}