GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing docs.ruby-lang.org — class Array - Documentation for Ruby 4.1 class ArrayAn Array object is an ordered, integer-indexed collection of objects, called elements; the object represents an array data structure. An element may be any object (even another array); elements may be any mixture of objects of different types. Important data structures that use arrays include: There are also array-like data structures:
Array IndexesArray indexing starts at 0, as in C or Java. A non-negative index is an offset from the first element:
A negative index is an offset, backwards, from the end of the array:
In-Range and Out-of-Range IndexesA non-negative index is in range if and only if it is smaller than the size of the array. For a 3-element array:
A negative index is in range if and only if its absolute value is not larger than the size of the array. For a 3-element array:
Effective IndexAlthough the effective index into an array is always an integer, some methods (both within class Array and elsewhere) accept one or more non-integer arguments that are integer-convertible objects. Creating ArraysYou can create an Array object explicitly with:
A number of Ruby methods, both in the core and in the standard library, provide instance method
Example UsageIn addition to the methods it mixes in through the Some of the more common ones are illustrated below. Accessing ElementsElements in an array can be retrieved using the arr = [1, 2, 3, 4, 5, 6] arr[2] #=> 3 arr[100] #=> nil arr[-3] #=> 4 arr[2, 3] #=> [3, 4, 5] arr[1..4] #=> [2, 3, 4, 5] arr[1..-3] #=> [2, 3, 4] Another way to access a particular array element is by using the arr.at(0) #=> 1 The To raise an error for indices outside of the array bounds or else to provide a default value when that happens, you can use arr = ['a', 'b', 'c', 'd', 'e', 'f'] arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6 arr.fetch(100, "oops") #=> "oops" The special methods arr.first #=> 1 arr.last #=> 6 To return the first arr.take(3) #=> [1, 2, 3]
arr.drop(3) #=> [4, 5, 6] Obtaining Information about an ArrayAn array keeps track of its own length at all times. To query an array about the number of elements it contains, use browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE'] browsers.length #=> 5 browsers.count #=> 5 To check whether an array contains any elements at all browsers.empty? #=> false To check whether a particular item is included in the array browsers.include?('Konqueror') #=> false Adding Items to an ArrayItems can be added to the end of an array by using either arr = [1, 2, 3, 4] arr.push(5) #=> [1, 2, 3, 4, 5] arr << 6 #=> [1, 2, 3, 4, 5, 6]
arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6] With arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6] Using the arr.insert(3, 'orange', 'pear', 'grapefruit') #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6] Removing Items from an ArrayThe method arr = [1, 2, 3, 4, 5, 6] arr.pop #=> 6 arr #=> [1, 2, 3, 4, 5] To retrieve and at the same time remove the first item, use arr.shift #=> 1 arr #=> [2, 3, 4, 5] To delete an element at a particular index: arr.delete_at(2) #=> 4 arr #=> [2, 3, 5] To delete a particular element anywhere in an array, use arr = [1, 2, 2, 3] arr.delete(2) #=> 2 arr #=> [1,3] A useful method if you need to remove arr = ['foo', 0, nil, 'bar', 7, 'baz', nil] arr.compact #=> ['foo', 0, 'bar', 7, 'baz'] arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil] arr.compact! #=> ['foo', 0, 'bar', 7, 'baz'] arr #=> ['foo', 0, 'bar', 7, 'baz'] Another common need is to remove duplicate elements from an array. It has the non-destructive arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556] arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123] Iterating over an ArrayLike all classes that include the Note that this operation leaves the array unchanged. arr = [1, 2, 3, 4, 5] arr.each {|a| print a -= 10, " "} # prints: -9 -8 -7 -6 -5 #=> [1, 2, 3, 4, 5] Another sometimes useful iterator is words = %w[first second third fourth fifth sixth] str = "" words.reverse_each {|word| str += "#{word} "} p str #=> "sixth fifth fourth third second first " The arr.map {|a| 2*a} #=> [2, 4, 6, 8, 10] arr #=> [1, 2, 3, 4, 5] arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25] arr #=> [1, 4, 9, 16, 25] Selecting Items from an ArrayElements can be selected from an array according to criteria defined in a block. The selection can happen in a destructive or a non-destructive manner. While the destructive operations will modify the array they were called on, the non-destructive methods usually return a new array with the selected elements, but leave the original array unchanged. Non-destructive Selectionarr = [1, 2, 3, 4, 5, 6] arr.select {|a| a > 3} #=> [4, 5, 6] arr.reject {|a| a < 3} #=> [3, 4, 5, 6] arr.drop_while {|a| a < 4} #=> [4, 5, 6] arr #=> [1, 2, 3, 4, 5, 6] Destructive Selection
Similar to arr.delete_if {|a| a < 4} #=> [4, 5, 6] arr #=> [4, 5, 6] arr = [1, 2, 3, 4, 5, 6] arr.keep_if {|a| a < 4} #=> [1, 2, 3] arr #=> [1, 2, 3] What’s HereFirst, what’s elsewhere. Class Array:
Here, class Array provides methods that are useful for: Methods for Creating an Array
See also Creating Arrays. Methods for Querying
Methods for Comparing
Methods for FetchingThese methods do not modify
Methods for AssigningThese methods add, replace, or reorder elements in
Methods for DeletingEach of these methods removes elements from
Methods for Combining
Methods for Iterating
Methods for Converting
Other Methods
{} Sourcestatic VALUE
rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
{
VALUE ary = ary_new(klass, argc);
if (argc > 0 && argv) {
ary_memcpy(ary, 0, argc, argv);
ARY_SET_LEN(ary, argc);
}
return ary;
}
Returns a new array, populated with the given objects: Array[1, 'a', /^A/] # => [1, "a", /^A/] Array[] # => [] Array.[](1, 'a', /^A/) # => [1, "a", /^A/] Related: see Methods for Creating an Array.
{} Sourcestatic VALUE
rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
{
rb_len_t len;
VALUE size, val;
rb_ary_modify(ary);
if (argc == 0) {
rb_ary_reset(ary);
RUBY_ASSERT(ARY_EMBED_P(ary));
RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0);
if (rb_block_given_p()) {
rb_warning("given block not used");
}
return ary;
}
rb_scan_args(argc, argv, "02", &size, &val);
if (argc == 1 && !FIXNUM_P(size)) {
val = rb_check_array_type(size);
if (!NIL_P(val)) {
rb_ary_replace(ary, val);
return ary;
}
}
len = NUM2LEN(size);
/* NUM2LEN() may call size.to_int, ary can be frozen, modified, etc */
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
/* recheck after argument conversion */
rb_ary_modify(ary);
ARY_SET_LEN(ary, 0);
ary_resize_capa(ary, len);
if (rb_block_given_p()) {
rb_len_t i;
if (argc == 2) {
rb_warn("block supersedes default value argument");
}
for (i=0; i<len; i++) {
rb_ary_store(ary, i, rb_yield(LEN2NUM(i)));
ARY_SET_LEN(ary, i + 1);
}
}
else {
ary_memfill(ary, 0, len, val);
ARY_SET_LEN(ary, len);
}
return ary;
}
Returns a new array. With no block and no argument given, returns a new empty array: Array.new # => [] With no block and array argument given, returns a new array with the same elements: Array.new([:foo, 'bar', 2]) # => [:foo, "bar", 2] With no block and integer argument given, returns a new array containing that many instances of the given Array.new(0) # => [] Array.new(3) # => [nil, nil, nil] Array.new(2, 3) # => [3, 3] With a block given, returns an array of the given Array.new(3) {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"] A common pitfall for new Rubyists is providing an expression as array = Array.new(2, {}) array # => [{}, {}] array[0][:a] = 1 array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object If you want the elements of the array to be distinct, you should pass a block: array = Array.new(2) { {} } array # => [{}, {}] array[0][:a] = 1 array # => [{a: 1}, {}], as array[0] and array[1] are different objects Raises Related: see Methods for Creating an Array. {} Sourcestatic VALUE
rb_ary_s_try_convert(VALUE dummy, VALUE ary)
{
return rb_check_array_type(ary);
}
Attempts to return an array, based on the given If Otherwise if Otherwise returns Related: see Methods for Creating an Array.
{} Sourcestatic VALUE
rb_ary_and(VALUE ary1, VALUE ary2)
{
ary2 = to_ary(ary2);
VALUE ary3 = rb_ary_new();
if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (rb_len_t i = 0; i < RARRAY_LEN(ary1); i++) {
VALUE v = RARRAY_AREF(ary1, i);
if (!rb_ary_includes_by_eql(ary2, v)) continue;
if (rb_ary_includes_by_eql(ary3, v)) continue;
rb_ary_push(ary3, v);
}
return ary3;
}
VALUE set = ary_to_set(ary2);
for (rb_len_t i = 0; i < RARRAY_LEN(ary1); i++) {
VALUE v = RARRAY_AREF(ary1, i);
if (rb_set_delete_no_check(set, v)) {
rb_ary_push(ary3, v);
}
}
return ary3;
}
Returns a new array containing the intersection of [0, 1, 2, 3] & [1, 2] # => [1, 2] Omits duplicates: [0, 1, 1, 0] & [0, 1] # => [0, 1] Preserves order from [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2] Identifies common elements using method Related: see Methods for Combining. static VALUE
rb_ary_times(VALUE ary, VALUE times)
{
VALUE ary2, tmp;
const VALUE *ptr;
rb_len_t t, len;
tmp = rb_check_string_type(times);
if (!NIL_P(tmp)) {
return rb_ary_join(ary, tmp);
}
len = NUM2LEN(times);
if (len == 0) {
ary2 = ary_new(rb_cArray, 0);
goto out;
}
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY_LEN(ary);
ary2 = ary_new(rb_cArray, len);
ARY_SET_LEN(ary2, len);
ptr = RARRAY_CONST_PTR(ary);
t = RARRAY_LEN(ary);
if (0 < t) {
ary_memcpy(ary2, 0, t, ptr);
while (t <= len/2) {
ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
t *= 2;
}
if (t < len) {
ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
}
}
out:
return ary2;
}
When non-negative integer argument a = ['x', 'y'] a * 3 # => ["x", "y", "x", "y", "x", "y"] When string argument [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {foo: 0}"
{} SourceVALUE
rb_ary_plus(VALUE x, VALUE y)
{
VALUE z;
rb_len_t len, xlen, ylen;
y = to_ary(y);
xlen = RARRAY_LEN(x);
ylen = RARRAY_LEN(y);
len = xlen + ylen;
z = rb_ary_new2(len);
ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
ARY_SET_LEN(z, len);
return z;
}
Returns a new array containing all elements of a = [0, 1] + [2, 3] a # => [0, 1, 2, 3] Related: see Methods for Combining.
{} SourceVALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
VALUE ary3 = rb_ary_new();
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (rb_len_t i = 0; i < RARRAY_LEN(ary1); i++) {
VALUE elt = rb_ary_elt(ary1, i);
if (rb_ary_includes_by_eql(ary2, elt)) continue;
rb_ary_push(ary3, elt);
}
return ary3;
}
VALUE set = ary_to_set(ary2);
for (rb_len_t i = 0; i < RARRAY_LEN(ary1); i++) {
if (rb_set_lookup(set, RARRAY_AREF(ary1, i))) continue;
rb_ary_push(ary3, rb_ary_elt(ary1, i));
}
return ary3;
}
Returns a new array containing only those elements of [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] [0, 1, 1, 2, 1, 1, 3, 1, 1] - [3, 2, 0, :foo] # => [1, 1, 1, 1, 1, 1] [0, 1, 2] - [:foo] # => [0, 1, 2] Element are compared using method Related: see Methods for Combining.
{} SourceVALUE
rb_ary_push(VALUE ary, VALUE item)
{
rb_len_t idx = RARRAY_LEN((ary_verify(ary), ary));
VALUE target_ary = ary_ensure_room_for_push(ary, 1);
RARRAY_PTR_USE(ary, ptr, {
RB_OBJ_WRITE(target_ary, &ptr[idx], item);
});
ARY_SET_LEN(ary, idx + 1);
ary_verify(ary);
return ary;
}
Appends [:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz] Appends [:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]] Related: see Methods for Assigning.
{} SourceVALUE
rb_ary_cmp(VALUE ary1, VALUE ary2)
{
rb_len_t len;
VALUE v;
ary2 = rb_check_array_type(ary2);
if (NIL_P(ary2)) return Qnil;
if (ary1 == ary2) return INT2FIX(0);
v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
if (!UNDEF_P(v)) return v;
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
if (len == 0) return INT2FIX(0);
if (len > 0) return INT2FIX(1);
return INT2FIX(-1);
}
Returns -1, 0, or 1 as Iterates over each index
When every [0, 1, 2] <=> [0, 1] # => 1 [0, 1, 2] <=> [0, 1, 2] # => 0 [0, 1, 2] <=> [0, 1, 2, 3] # => -1 Note that when [0, 1, 2] <=> [0, 1, 2, -3] # => -1 [0, 1, 2] <=> [0, 1, 2, 0] # => -1 [0, 1, 2] <=> [0, 1, 2, 3] # => -1 Related: see Methods for Comparing.
{} Sourcestatic VALUE
rb_ary_equal(VALUE ary1, VALUE ary2)
{
if (ary1 == ary2) return Qtrue;
if (!RB_TYPE_P(ary2, T_ARRAY)) {
if (!rb_respond_to(ary2, idTo_ary)) {
return Qfalse;
}
return rb_equal(ary2, ary1);
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}
Returns whether both:
Examples: [:foo, 'bar', 2] == [:foo, 'bar', 2] # => true [:foo, 'bar', 2] == [:foo, 'bar', 2.0] # => true [:foo, 'bar', 2] == [:foo, 'bar'] # => false # Different sizes. [:foo, 'bar', 2] == [:foo, 'bar', 3] # => false # Different elements. This method is different from method Related: see Methods for Comparing. VALUE
rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
{
rb_check_arity(argc, 1, 2);
if (argc == 2) {
return rb_ary_aref2(ary, argv[0], argv[1]);
}
return rb_ary_aref1(ary, argv[0]);
}
Returns elements from In Brief a = [:foo, 'bar', 2] # Single argument offset: returns one element. a[0] # => :foo # Zero-based index. a[-1] # => 2 # Negative index counts backwards from end. # Arguments offset and size: returns an array. a[1, 2] # => ["bar", 2] a[-2, 2] # => ["bar", 2] # Negative offset counts backwards from end. # Single argument range: returns an array. a[0..1] # => [:foo, "bar"] a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end. a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end. Argument When the single integer argument a = [:foo, 'bar', 2] a[0] # => :foo a[2] # => 2 a # => [:foo, "bar", 2] If a = [:foo, 'bar', 2] a[-1] # => 2 a[-2] # => "bar" If Arguments When integer arguments a = [:foo, 'bar', 2] a[0, 2] # => [:foo, "bar"] a[1, 2] # => ["bar", 2] If a = [:foo, 'bar', 2] a[0, 4] # => [:foo, "bar", 2] a[1, 3] # => ["bar", 2] a[2, 2] # => [2] If If Argument When bounded range argument a = [:foo, 'bar', 2] a[0..1] # => [:foo, "bar"] a[1..2] # => ["bar", 2] Special case: If If a = [:foo, 'bar', 2] a[0..-1] # => [:foo, "bar", 2] a[0..-2] # => [:foo, "bar"] a[0..-3] # => [:foo] If a = [:foo, 'bar', 2] a[-1..2] # => [2] a[-2..2] # => ["bar", 2] a[-3..2] # => [:foo, "bar", 2] If a = [:foo, 'bar', 2] a[4..1] # => nil a[4..0] # => nil a[4..-1] # => nil With beginless range a = %w[foo bar baz] # => ["foo", "bar", "baz"] a[..0] # => ["foo"] a[..2] # => ["foo", "bar", "baz"] a[..5] # => ["foo", "bar", "baz"] a[..-1] # => ["foo", "bar", "baz"] a[..-3] # => ["foo"] a[..-5] # => [] With endless range a = %w[foo bar baz] # => ["foo", "bar", "baz"] a[0..] # => ["foo", "bar", "baz"] a[2..] # => ["baz"] a[4..] # => nil a[-1..] # => ["baz"] a[-3..] # => ["foo", "bar", "baz"] a[-5..] # => nil With unbounded range a = %w[foo bar baz] # => ["foo", "bar", "baz"] a[nil..nil] # => ["foo", "bar", "baz"] Argument When a single a = ['--', 'data1', '--', 'data2', '--', 'data3'] a[(1..).step(2)] # => ["data1", "data2", "data3"] Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throws a = ['--', 'data1', '--', 'data2', '--', 'data3'] a[(1..11).step(2)] # RangeError (((1..11).step(2)) out of range) a[(7..).step(2)] # RangeError (((7..).step(2)) out of range) If given a single argument, and its type is not one of the listed, tries to convert it to a = [:foo, 'bar', 2] # Raises TypeError (no implicit conversion of Symbol into Integer): a[:foo] Related: see Methods for Fetching.
Also aliased as: slice
{} Sourcestatic VALUE
rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
rb_len_t offset, beg, len;
rb_check_arity(argc, 2, 3);
rb_ary_modify_check(ary);
if (argc == 3) {
beg = NUM2LEN(argv[0]);
len = NUM2LEN(argv[1]);
return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
}
if (FIXNUM_P(argv[0])) {
offset = FIX2LEN(argv[0]);
return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
/* check if idx is Range */
return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
}
offset = NUM2LEN(argv[0]);
return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
Assigns elements in In brief: a_orig = [:foo, 'bar', 2] # With argument index. a = a_orig.dup a[0] = 'foo' # => "foo" a # => ["foo", "bar", 2] a = a_orig.dup a[7] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"] # With arguments start and length. a = a_orig.dup a[0, 2] = 'foo' # => "foo" a # => ["foo", 2] a = a_orig.dup a[6, 50] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, "foo"] # With argument range. a = a_orig.dup a[0..1] = 'foo' # => "foo" a # => ["foo", 2] a = a_orig.dup a[6..50] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, "foo"] When If a = [:foo, 'bar', 2] a[0] = 'foo' # => "foo" a # => ["foo", "bar", 2] If a = [:foo, 'bar', 2] a[7] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"] If a = [:foo, 'bar', 2] a[-1] = 'two' # => "two" a # => [:foo, "bar", "two"] When a = [:foo, 'bar', 2] a[0, 2] = 'foo' # => "foo" a # => ["foo", 2] If a = [:foo, 'bar', 2] a[-2, 2] = 'foo' # => "foo" a # => [:foo, "foo"] If a = [:foo, 'bar', 2] a[6, 50] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, "foo"] If a = [:foo, 'bar', 2] a[1, 0] = 'foo' # => "foo" a # => [:foo, "foo", "bar", 2] If a = [:foo, 'bar', 2] a[1, 5] = 'foo' # => "foo" a # => [:foo, "foo"] When a = [:foo, 'bar', 2] a[0..1] = 'foo' # => "foo" a # => ["foo", 2] if a = [:foo, 'bar', 2] a[-2..2] = 'foo' # => "foo" a # => [:foo, "foo"] If the array length is less than a = [:foo, 'bar', 2] a[6..50] = 'foo' # => "foo" a # => [:foo, "bar", 2, nil, nil, nil, "foo"] If a = [:foo, 'bar', 2] a[1..0] = 'foo' # => "foo" a # => [:foo, "foo", "bar", 2] If a = [:foo, 'bar', 2] a[1..-1] = 'foo' # => "foo" a # => [:foo, "foo"] a = [:foo, 'bar', 2] a[1..-2] = 'foo' # => "foo" a # => [:foo, "foo", 2] a = [:foo, 'bar', 2] a[1..-3] = 'foo' # => "foo" a # => [:foo, "foo", "bar", 2] a = [:foo, 'bar', 2] If a = [:foo, 'bar', 2] a[1..5] = 'foo' # => "foo" a # => [:foo, "foo"] Related: see Methods for Assigning.
{} Sourcestatic VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
VALUE ary3 = rb_ary_new();
rb_ary_union(ary3, ary1);
rb_ary_union(ary3, ary2);
return ary3;
}
VALUE set = rb_obj_hide(rb_set_new_capa(RARRAY_LEN(ary1) + RARRAY_LEN(ary2)));
rb_ary_union_set(set, ary1);
rb_ary_union_set(set, ary2);
return rb_set_to_a(set);
}
Returns the union of [0, 1] | [2, 3] # => [0, 1, 2, 3] [0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3] [0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3] Related: see Methods for Combining.
{} Sourcestatic VALUE
rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
{
rb_len_t i, len = RARRAY_LEN(ary);
rb_check_arity(argc, 0, 1);
if (!len) return Qtrue;
if (argc) {
if (rb_block_given_p()) {
rb_warn("given block not used");
}
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
}
}
else if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) {
if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
}
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
}
}
return Qtrue;
}
Returns whether for every element of With no block and no argument, returns whether every element of [[], {}, '', 0, 0.0, Object.new].all? # => true # All truthy objects.
[[], {}, '', 0, 0.0, nil].all? # => false # nil is not truthy.
[[], {}, '', 0, 0.0, false].all? # => false # false is not truthy.
With argument [0, 0, 0].all?(0) # => true [0, 1, 2].all?(1) # => false ['food', 'fool', 'foot'].all?(/foo/) # => true ['food', 'drink'].all?(/foo/) # => false With a block given, calls the block with each element in [0, 1, 2].all? { |ele| ele < 3 } # => true [0, 1, 2].all? { |ele| ele < 2 } # => false With both a block and argument Special case: returns Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
{
rb_len_t i, len = RARRAY_LEN(ary);
rb_check_arity(argc, 0, 1);
if (!len) return Qfalse;
if (argc) {
if (rb_block_given_p()) {
rb_warn("given block not used");
}
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
}
}
else if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) {
if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
}
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
}
}
return Qfalse;
}
Returns whether for any element of With no block and no argument, returns whether any element of [nil, false, []].any? # => true # Array object is truthy. [nil, false, {}].any? # => true # Hash object is truthy. [nil, false, ''].any? # => true # String object is truthy. [nil, false].any? # => false # Nil and false are not truthy. With argument [nil, false, 0].any?(0) # => true [nil, false, 1].any?(0) # => false [nil, false, 'food'].any?(/foo/) # => true [nil, false, 'food'].any?(/bar/) # => false With a block given, calls the block with each element in [0, 1, 2].any? {|ele| ele < 1 } # => true [0, 1, 2].any? {|ele| ele < 0 } # => false With both a block and argument Special case: returns Related: see Methods for Querying.
Appends each argument in a = [:foo, 'bar', 2] # => [:foo, "bar", 2] a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] Appends each argument as a single element, even if it is another array: a = [:foo, 'bar', 2] # => [:foo, "bar", 2] a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] Related: see Methods for Assigning.
Alias for: push
{} SourceVALUE
rb_ary_assoc(VALUE ary, VALUE key)
{
rb_len_t i;
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = rb_check_array_type(RARRAY_AREF(ary, i));
if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
rb_equal(RARRAY_AREF(v, 0), key))
return v;
}
return Qnil;
}
Returns the first element a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] a.assoc(4) # => [4, 5, 6] Returns Related:
{} SourceVALUE
rb_ary_at(VALUE ary, VALUE pos)
{
return rb_ary_entry(ary, NUM2LEN(pos));
}
Returns the element of For non-negative a = [:foo, 'bar', 2] a.at(0) # => :foo a.at(2) # => 2 a.at(2.0) # => 2 For negative a.at(-2) # => "bar" Related:
{} Sourcestatic VALUE
rb_ary_bsearch(VALUE ary)
{
VALUE index_result = rb_ary_bsearch_index(ary);
if (RB_INTEGER_TYPE_P(index_result)) {
return rb_ary_entry(ary, NUM2LEN(index_result));
}
return index_result;
}
Returns the element from See Binary Searching. Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_bsearch_index(VALUE ary)
{
rb_len_t low = 0, high = RARRAY_LEN(ary), mid;
int smaller = 0, satisfied = 0;
VALUE v, val;
RETURN_ENUMERATOR(ary, 0, 0);
while (low < high) {
mid = low + ((high - low) / 2);
val = rb_ary_entry(ary, mid);
v = rb_yield(val);
if (FIXNUM_P(v)) {
if (v == INT2FIX(0)) return LEN2NUM(mid);
smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
}
else if (v == Qtrue) {
satisfied = 1;
smaller = 1;
}
else if (!RTEST(v)) {
smaller = 0;
}
else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
const VALUE zero = INT2FIX(0);
switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
case 0: return LEN2NUM(mid);
case 1: smaller = 0; break;
case -1: smaller = 1;
}
}
else {
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
" (must be numeric, true, false or nil)",
rb_obj_class(v));
}
if (smaller) {
high = mid;
}
else {
low = mid + 1;
}
}
if (!satisfied) return Qnil;
return LEN2NUM(low);
}
Returns the integer index of the element from See Binary Searching. Related: see Methods for Fetching.
{} SourceVALUE
rb_ary_clear(VALUE ary)
{
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
ARY_SET_EMBED_LEN(ary, 0);
}
else {
ARY_SET_LEN(ary, 0);
if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
}
}
ary_verify(ary);
return ary;
}
Removes all elements from a = [:foo, 'bar', 2] a.clear # => [] Related: see Methods for Deleting.
{} Sourcestatic VALUE
rb_ary_collect(VALUE ary)
{
rb_len_t i;
VALUE collect;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
collect = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
}
return collect;
}
With a block given, calls the block with each element of a = [:foo, 'bar', 2] a1 = a.map {|element| element.class } a1 # => [Symbol, String, Integer] With no block given, returns a new Related:
Also aliased as: map
{} Sourcestatic VALUE
rb_ary_collect_bang(VALUE ary)
{
rb_len_t i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
}
return ary;
}
With a block given, calls the block with each element of a = [:foo, 'bar', 2] a.map! { |element| element.class } # => [Symbol, String, Integer] With no block given, returns a new Related:
Also aliased as: map!
{} Sourcestatic VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
rb_len_t i, n, len;
n = NUM2LEN(num);
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
len = RARRAY_LEN(ary);
if (n < 0 || len < n) {
/* yield nothing */
}
else if (n == 0) {
rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else {
VALUE ary0 = ary_make_hidden_shared_copy(ary); /* private defensive copy of ary */
volatile VALUE t0;
rb_len_t *stack = ALLOCV_N(rb_len_t, t0, n+1);
combinate0(len, n, stack, ary0);
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
When a block and a positive integer-convertible object argument a = %w[a b c] # => ["a", "b", "c"] a.combination(2) {|combination| p combination } # => ["a", "b", "c"] Output: ["a", "b"] ["a", "c"] ["b", "c"] The order of the yielded combinations is not guaranteed. When a.combination(0) {|combination| p combination } [].combination(0) {|combination| p combination } Output: [] [] When a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] With no block given, returns a new Related:
{} Sourcestatic VALUE
rb_ary_compact(VALUE ary)
{
ary = rb_ary_dup(ary);
rb_ary_compact_bang(ary);
return ary;
}
Returns a new array containing only the non- a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] a.compact # => [0, false, "", [], {}] Related:
{} SourceVALUE
rb_ary_compact_bang(VALUE ary)
{
VALUE *p, *t, *end;
rb_len_t n;
rb_ary_modify(ary);
p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
end = p + RARRAY_LEN(ary);
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
n = p - RARRAY_CONST_PTR(ary);
if (RARRAY_LEN(ary) == n) {
return Qnil;
}
ary_resize_smaller(ary, n);
return ary;
}
Removes all a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] a.compact! # => [0, false, "", [], {}] a # => [0, false, "", [], {}] a.compact! # => nil Related:
{} Sourcestatic VALUE
rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
{
rb_ary_modify_check(ary);
if (argc == 1) {
rb_ary_concat(ary, argv[0]);
}
else if (argc > 1) {
int i;
VALUE args = rb_ary_hidden_new(argc);
for (i = 0; i < argc; i++) {
rb_ary_concat(args, argv[i]);
}
ary_append(ary, args);
}
ary_verify(ary);
return ary;
}
Adds to a = [0, 1] a.concat(['two', 'three'], [:four, :five], a) # => [0, 1, "two", "three", :four, :five, 0, 1] Related: see Methods for Assigning. static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
rb_len_t i, n = 0;
if (rb_check_arity(argc, 0, 1) == 0) {
VALUE v;
if (!rb_block_given_p())
return LEN2NUM(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
if (RTEST(rb_yield(v))) n++;
}
}
else {
VALUE obj = argv[0];
if (rb_block_given_p()) {
rb_warn("given block not used");
}
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
}
}
return LEN2NUM(n);
}
Returns a count of specified elements. With no argument and no block, returns the count of all elements: [0, :one, 'two', 3, 3.0].count # => 5 With argument [0, :one, 'two', 3, 3.0].count(3) # => 2 With no argument and a block given, calls the block with each element; returns the count of elements for which the block returns a truthy value: [0, 1, 2, 3].count {|element| element > 1 } # => 2 With argument Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
{
rb_len_t n, i;
rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
if (argc == 0 || NIL_P(argv[0])) {
n = -1;
}
else {
n = NUM2LEN(argv[0]);
if (n <= 0) return Qnil;
}
while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
}
return Qnil;
}
With a block given, may call the block, depending on the value of argument When output = [] [0, 1].cycle(2) {|element| output.push(element) } # => nil output # => [0, 1, 0, 1] When [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil When # Prints 0 and 1 forever. [0, 1].cycle {|element| puts element } [0, 1].cycle(nil) {|element| puts element } With no block given, returns a new Related: see Methods for Iterating.
{} SourceVALUE
rb_ary_delete(VALUE ary, VALUE item)
{
VALUE v = item;
rb_len_t i1, i2;
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
VALUE e = RARRAY_AREF(ary, i1);
if (rb_equal(e, item)) {
v = e;
continue;
}
if (i1 != i2) {
rb_ary_store(ary, i2, e);
}
i2++;
}
if (RARRAY_LEN(ary) == i2) {
if (rb_block_given_p()) {
return rb_yield(item);
}
return Qnil;
}
ary_resize_smaller(ary, i2);
ary_verify(ary);
return v;
}
Removes zero or more elements from With no block given, removes from a = [0, 1, 2, 2.0] a.delete(2) # => 2.0 a # => [0, 1] Returns a.delete(2) # => nil With a block given, removes from If any such elements are found, ignores the block and returns the last removed element: a = [0, 1, 2, 2.0] a.delete(2) {|element| fail 'Cannot happen' } # => 2.0 a # => [0, 1] If no such element is found, returns the block’s return value: a.delete(2) {|element| "Element #{element} not found." } # => "Element 2 not found." Related: see Methods for Deleting.
{} Sourcestatic VALUE
rb_ary_delete_at_m(VALUE ary, VALUE pos)
{
return rb_ary_delete_at(ary, NUM2LEN(pos));
}
Removes the element of When a = [:foo, 'bar', 2] a.delete_at(1) # => "bar" a # => [:foo, 2] When a = [:foo, 'bar', 2] a.delete_at(-2) # => "bar" a # => [:foo, 2] When a = [:foo, 'bar', 2] a.delete_at(3) # => nil a.delete_at(-4) # => nil Related: see Methods for Deleting.
{} Sourcestatic VALUE
rb_ary_delete_if(VALUE ary)
{
ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
ary_reject_bang(ary);
return ary;
}
With a block given, calls the block with each element of a = [:foo, 'bar', 2, 'bat'] a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2] With no block given, returns a new Related: see Methods for Deleting.
Alias for: find
{} Sourcestatic VALUE
rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
{
volatile VALUE t0;
bool *is_set = ALLOCV_N(bool, t0, argc);
VALUE ary_diff = rb_ary_new();
rb_len_t length = RARRAY_LEN(ary);
for (rb_len_t i = 0; i < argc; i++) {
argv[i] = to_ary(argv[i]);
is_set[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
if (is_set[i]) {
argv[i] = ary_to_set(argv[i]);
}
}
for (rb_len_t i = 0; i < RARRAY_LEN(ary); i++) {
int j;
VALUE elt = rb_ary_elt(ary, i);
for (j = 0; j < argc; j++) {
if (is_set[j]) {
if (rb_set_lookup(argv[j], elt))
break;
}
else {
if (rb_ary_includes_by_eql(argv[j], elt)) break;
}
}
if (j == argc) rb_ary_push(ary_diff, elt);
}
ALLOCV_END(t0);
return ary_diff;
}
Returns a new array containing only those elements from [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3] [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] [0, 1, 2].difference([4]) # => [0, 1, 2] [0, 1, 2].difference # => [0, 1, 2] Returns a copy of Related:
{} Sourcestatic VALUE
rb_ary_dig(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
self = rb_ary_at(self, *argv);
if (!--argc) return self;
++argv;
return rb_obj_dig(argc, argv, self, Qnil);
}
Finds and returns the object in nested object specified by Examples: a = [:foo, [:bar, :baz, [:bat, :bam]]] a.dig(1) # => [:bar, :baz, [:bat, :bam]] a.dig(1, 2) # => [:bat, :bam] a.dig(1, 2, 0) # => :bat a.dig(1, 2, 3) # => nil Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_drop(VALUE ary, VALUE n)
{
VALUE result;
rb_len_t pos = NUM2LEN(n);
if (pos < 0) {
rb_raise(rb_eArgError, "attempt to drop negative size");
}
result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
if (NIL_P(result)) result = rb_ary_new();
return result;
}
Returns a new array containing all but the first Examples: a = [0, 1, 2, 3, 4, 5] a.drop(0) # => [0, 1, 2, 3, 4, 5] a.drop(1) # => [1, 2, 3, 4, 5] a.drop(2) # => [2, 3, 4, 5] a.drop(9) # => [] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_drop_while(VALUE ary)
{
rb_len_t i;
RETURN_ENUMERATOR(ary, 0, 0);
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
}
return rb_ary_drop(ary, LEN2NUM(i));
}
With a block given, calls the block with each successive element of a = [0, 1, 2, 3, 4, 5] a.drop_while {|element| element < 3 } # => [3, 4, 5] With no block given, returns a new Related: see Methods for Fetching.
{} SourceVALUE
rb_ary_each(VALUE ary)
{
rb_len_t i;
ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_execution_context_t *ec = GET_EC();
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_ec_yield(ec, RARRAY_AREF(ary, i));
}
return ary;
}
With a block given, iterates over the elements of a = [:foo, 'bar', 2] a.each {|element| puts "#{element.class} #{element}" } Output: Symbol foo String bar Integer 2 Allows the array to be modified during iteration: a = [:foo, 'bar', 2] a.each {|element| puts element; a.clear if element.to_s.start_with?('b') } Output: foo bar With no block given, returns a new Related: see Methods for Iterating.
{} Source# File array.rb, line 246 def each_index Primitive.attr! :inline_block, :without_interrupts unless defined?(yield) return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, ary_enum_length)' end i = 0 until Primitive.rb_builtin_ary_at_end(i) yield i i = Primitive.rb_builtin_fixnum_inc(i) end self end With a block given, iterates over the elements of a = [:foo, 'bar', 2] a.each_index {|index| puts "#{index} #{a[index]}" } Output: 0 foo 1 bar 2 2 Allows the array to be modified during iteration: a = [:foo, 'bar', 2] a.each_index {|index| puts index; a.clear if index > 0 } a # => [] Output: 0 1 With no block given, returns a new Related: see Methods for Iterating.
{} Sourcestatic VALUE
rb_ary_empty_p(VALUE ary)
{
return RBOOL(RARRAY_LEN(ary) == 0);
}
Returns Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_eql(VALUE ary1, VALUE ary2)
{
if (ary1 == ary2) return Qtrue;
if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
}
Returns a0 = [:foo, 'bar', 2] a1 = [:foo, 'bar', 2] a1.eql?(a0) # => true Otherwise, returns This method is different from method Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
{
VALUE pos, ifnone;
long block_given;
rb_len_t idx;
rb_scan_args(argc, argv, "11", &pos, &ifnone);
block_given = rb_block_given_p();
if (block_given && argc == 2) {
rb_warn("block supersedes default value argument");
}
idx = NUM2LEN(pos);
if (idx < 0) {
idx += RARRAY_LEN(ary);
}
if (idx < 0 || RARRAY_LEN(ary) <= idx) {
if (block_given) return rb_yield(pos);
if (argc == 1) {
rb_raise(rb_eIndexError, "index %"PRIdLEN" outside of array bounds: %"PRIdLEN"...%"PRIdLEN,
idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
}
return ifnone;
}
return RARRAY_AREF(ary, idx);
}
Returns the element of With the single argument a = [:foo, 'bar', 2] a.fetch(1) # => "bar" a.fetch(1.1) # => "bar" If a = [:foo, 'bar', 2] a.fetch(-1) # => 2 a.fetch(-2) # => "bar" With arguments a = [:foo, 'bar', 2] a.fetch(1, nil) # => "bar" a.fetch(3, :foo) # => :foo With argument a = [:foo, 'bar', 2] a.fetch(1) {|index| raise 'Cannot happen' } # => "bar" a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50" Related: see Methods for Fetching. # File array.rb, line 210 def fetch_values(*indexes, &block) indexes.map! { |i| fetch(i, &block) } indexes end With no block given, returns a new array containing the elements of a = [:foo, :bar, :baz] a.fetch_values(2, 0) # => [:baz, :foo] a.fetch_values(2.1, 0) # => [:baz, :foo] a.fetch_values # => [] For a negative index, counts backwards from the end of the array: a.fetch_values(-2, -1) # [:bar, :baz] When no block is given, raises an exception if any index is out of range. With a block given, for each index:
Example: a = [:foo, :bar, :baz] a.fetch_values(1, 0, 42, 777) { |index| index.to_s } # => [:bar, :foo, "42", "777"] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_fill(int argc, VALUE *argv, VALUE ary)
{
VALUE item = Qundef, arg1, arg2;
rb_len_t beg = 0, end = 0, len = 0;
if (rb_block_given_p()) {
rb_scan_args(argc, argv, "02", &arg1, &arg2);
argc += 1; /* hackish */
}
else {
rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
}
switch (argc) {
case 1:
beg = 0;
len = RARRAY_LEN(ary);
break;
case 2:
if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
break;
}
/* fall through */
case 3:
beg = NIL_P(arg1) ? 0 : NUM2LEN(arg1);
if (beg < 0) {
beg = RARRAY_LEN(ary) + beg;
if (beg < 0) beg = 0;
}
len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LEN(arg2);
break;
}
rb_ary_modify(ary);
if (len < 0) {
return ary;
}
if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
rb_raise(rb_eArgError, "argument too big");
}
end = beg + len;
if (RARRAY_LEN(ary) < end) {
if (end >= ARY_CAPA(ary)) {
ary_resize_capa(ary, end);
}
ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
ARY_SET_LEN(ary, end);
}
if (UNDEF_P(item)) {
VALUE v;
rb_len_t i;
for (i=beg; i<end; i++) {
v = rb_yield(LEN2NUM(i));
if (i>=RARRAY_LEN(ary)) break;
rb_ary_modify(ary);
ARY_SET(ary, i, v);
}
}
else {
ary_memfill(ary, beg, len, item);
}
return ary;
}
Replaces selected elements in In brief: # Non-negative start. ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] # Extends with specified values if necessary. ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] # Fills with nils if necessary. ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"] # For negative start, counts backwards from the end. ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"] # Range. ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"] When arguments
With argument o = Object.new # => #<Object:0x0000014e7bff7600> a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] a.fill(o, 1, 2) # => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "d"] With a block given, the block is called once for each element to be replaced; the value passed to the block is the index of the element to be replaced (not the element itself); the block’s return value replaces the element: a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"] For arguments
When argument
Related: see Methods for Assigning.
With a block given, calls the block with each element of a = [:foo, 'bar', 2, :bam] a.select {|element| element.to_s.start_with?('b') } # => ["bar", :bam] With no block given, returns a new Related: see Methods for Fetching.
Alias for: select
With a block given, calls the block with each element of Returns a = [:foo, 'bar', 2, :bam] a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam] Returns With no block given, returns a new Related: see Methods for Deleting.
Alias for: select!
{} Sourcestatic VALUE
rb_ary_find(int argc, VALUE *argv, VALUE ary)
{
VALUE if_none;
rb_len_t idx;
if_none = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
RETURN_ENUMERATOR(ary, argc, argv);
for (idx = 0; idx < RARRAY_LEN(ary); idx++) {
VALUE elem = RARRAY_AREF(ary, idx);
if (RTEST(rb_yield(elem))) {
return elem;
}
}
if (!NIL_P(if_none)) {
return rb_funcallv(if_none, idCall, 0, 0);
}
return Qnil;
}
Returns the first element for which the block returns a truthy value. With a block given, calls the block with successive elements of the array; returns the first element for which the block returns a truthy value: [1, 3, 5].find {|element| element > 2} # => 3 If no such element is found, calls [1, 3, 5].find(proc {-1}) {|element| element > 12} # => -1 With no block given, returns an
Also aliased as: detect
{} Sourcestatic VALUE
rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
VALUE val;
rb_len_t i;
if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
return LEN2NUM(i);
}
}
return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LEN2NUM(i);
}
}
return Qnil;
}
Returns the zero-based integer index of a specified element, or With only argument a = [:foo, 'bar', 2, 'bar'] a.index('bar') # => 1 Returns With only a block given, calls the block with each successive element; returns the index of the first element for which the block returns a truthy value: a = [:foo, 'bar', 2, 'bar'] a.index {|element| element == 'bar' } # => 1 Returns With neither an argument nor a block given, returns a new Related: see Methods for Querying.
Also aliased as: index
{} Source# File array.rb, line 129 def first n = unspecified = true if Primitive.mandatory_only? Primitive.attr! :leaf Primitive.rb_builtin_ary_first else if unspecified Primitive.rb_builtin_ary_first else Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LEN(n), ARY_TAKE_FIRST) } end end end Returns elements from With no argument given, returns the first element (if available): a = [:foo, 'bar', 2] a.first # => :foo a # => [:foo, "bar", 2] If [].first # => nil With a non-negative integer argument a.first(0) # => [] a.first(2) # => [:foo, "bar"] a.first(50) # => [:foo, "bar", 2] Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
{
int level = -1;
VALUE result;
if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
level = NUM2INT(argv[0]);
if (level == 0) return ary_make_shared_copy(ary);
}
VALUE child = single_nested_array(ary);
if (child) {
if (level == 1) {
result = child;
}
else {
level--;
result = flatten(child, level);
}
}
else {
result = flatten(ary, level);
}
if (result == ary || result == child) {
return ary_make_shared_copy(result);
}
return result;
}
Returns a new array that is a recursive flattening of
With non-negative integer argument a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] a # => [0, [1, [2, 3], 4], 5, {foo: 0}, Set[6, 7]] a.flatten(0) # => [0, [1, [2, 3], 4], 5, {foo: 0}, Set[6, 7]] a.flatten(1 ) # => [0, 1, [2, 3], 4, 5, {foo: 0}, Set[6, 7]] a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {foo: 0}, Set[6, 7]] a.flatten(2) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] a.flatten(3) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] With a.flatten # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] Related:
{} Sourcestatic VALUE
rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
{
int mod = 0, level = -1;
VALUE result, lv;
lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
rb_ary_modify_check(ary);
if (!NIL_P(lv)) level = NUM2INT(lv);
if (level == 0) return Qnil;
VALUE child = single_nested_array(ary);
if (child) {
if (level == 1) {
result = child;
}
else {
if (level > 1) level--;
result = flatten(child, level);
}
}
else {
result = flatten(ary, level);
if (result == ary) {
return Qnil;
}
}
if (result != child && !(mod = ARY_EMBED_P(result))) rb_ary_freeze(result);
rb_ary_replace(ary, result);
if (mod) ARY_SET_EMBED_LEN(result, 0);
return ary;
}
Returns
Returns With non-negative integer argument a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] a # => [0, [1, [2, 3], 4], 5, {foo: 0}, Set[6, 7]] a.dup.flatten!(1) # => [0, 1, [2, 3], 4, 5, {foo: 0}, Set[6, 7]] a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {foo: 0}, Set[6, 7]] a.dup.flatten!(2) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] a.dup.flatten!(3) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] With a.dup.flatten! # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {foo: 0}, Set[6, 7]] Related:
{} SourceVALUE
rb_ary_freeze(VALUE ary)
{
RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY));
if (OBJ_FROZEN(ary)) return ary;
if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {
ary_shrink_capa(ary);
}
return rb_obj_freeze(ary);
}
Freezes
{} Sourcestatic VALUE
rb_ary_hash(VALUE ary)
{
RBIMPL_ASSERT_OR_ASSUME(ary);
return ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary), ary);
}
Returns the integer hash value for Two arrays with the same content will have the same hash value (and will compare using eql?): ['a', 'b'].hash == ['a', 'b'].hash # => true ['a', 'b'].hash == ['a', 'c'].hash # => false ['a', 'b'].hash == ['a'].hash # => false
{} SourceVALUE
rb_ary_includes(VALUE ary, VALUE item)
{
rb_len_t i;
VALUE e;
for (i=0; i<RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (rb_equal(e, item)) {
return Qtrue;
}
}
return Qfalse;
}
Returns whether for some element [0, 1, 2].include?(2) # => true [0, 1, 2].include?(2.0) # => true [0, 1, 2].include?(2.1) # => false Related: see Methods for Querying.
Returns the zero-based integer index of a specified element, or With only argument a = [:foo, 'bar', 2, 'bar'] a.index('bar') # => 1 Returns With only a block given, calls the block with each successive element; returns the index of the first element for which the block returns a truthy value: a = [:foo, 'bar', 2, 'bar'] a.index {|element| element == 'bar' } # => 1 Returns With neither an argument nor a block given, returns a new Related: see Methods for Querying.
Alias for: find_index
{} SourceVALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
rb_ary_modify_check(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
rb_ary_reset(copy);
/* orig has enough space to embed the contents of orig. */
if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
RUBY_ASSERT(ARY_EMBED_P(copy));
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
}
/* orig is embedded but copy does not have enough space to embed the
* contents of orig. */
else if (ARY_EMBED_P(orig)) {
rb_len_t len = ARY_EMBED_LEN(orig);
VALUE *ptr = ary_heap_alloc_buffer(len);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ptr);
ARY_SET_LEN(copy, len);
ARY_SET_CAPA(copy, len);
// No allocation and exception expected that could leave `copy` in a
// bad state from the edits above.
ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
}
/* Otherwise, orig is on heap and copy does not have enough space to embed
* the contents of orig. */
else {
VALUE shared_root = ary_make_shared(orig);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
rb_ary_set_shared(copy, shared_root);
RUBY_ASSERT(RB_OBJ_SHAREABLE_P(copy) ? RB_OBJ_SHAREABLE_P(shared_root) : 1);
}
ary_verify(copy);
return copy;
}
Replaces the elements of a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.replace(['d', 'e']) # => ["d", "e"] Related: see Methods for Assigning.
Also aliased as: replace
{} Sourcestatic VALUE
rb_ary_insert(int argc, VALUE *argv, VALUE ary)
{
rb_len_t pos;
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
rb_ary_modify_check(ary);
pos = NUM2LEN(argv[0]);
if (argc == 1) return ary;
if (pos == -1) {
pos = RARRAY_LEN(ary);
}
else if (pos < 0) {
rb_len_t minpos = -RARRAY_LEN(ary) - 1;
if (pos < minpos) {
rb_raise(rb_eIndexError, "index %"PRIdLEN" too small for array; minimum: %"PRIdLEN,
pos, minpos);
}
pos++;
}
ary_splice(ary, pos, 0, argv + 1, argc - 1, FALSE);
return ary;
}
Inserts the given When a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.insert(1, :x, :y, :z) # => ["a", :x, :y, :z, "b", "c"] Extends the array if a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z] When a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"] With no a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.insert(1) # => ["a", "b", "c"] a.insert(50) # => ["a", "b", "c"] a.insert(-50) # => ["a", "b", "c"] Raises Related: see Methods for Assigning. {} Sourcestatic VALUE
rb_ary_inspect(VALUE ary)
{
if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
return rb_exec_recursive(inspect_ary, ary, 0);
}
Returns the new string formed by calling method a = [:foo, 'bar', 2] a.inspect # => "[:foo, \"bar\", 2]" Related: see Methods for Converting.
Also aliased as: to_s
{} Sourcestatic VALUE
rb_ary_intersect_p(VALUE ary1, VALUE ary2)
{
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (rb_len_t i = 0; i < RARRAY_LEN(ary1); i++) {
VALUE v = RARRAY_AREF(ary1, i);
if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
}
return Qfalse;
}
VALUE shorter = ary1;
VALUE longer = ary2;
if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
longer = ary1;
shorter = ary2;
}
VALUE set = ary_to_set(shorter);
VALUE result = Qfalse;
for (rb_len_t i = 0; i < RARRAY_LEN(longer); i++) {
VALUE v = RARRAY_AREF(longer, i);
if (rb_set_lookup(set, v)) {
result = Qtrue;
break;
}
}
return result;
}
Returns whether [1, 2, 3].intersect?([3, 4, 5]) # => true [1, 2, 3].intersect?([4, 5, 6]) # => false Each element must correctly implement method Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
{
VALUE result = rb_ary_dup(ary);
int i;
for (i = 0; i < argc; i++) {
result = rb_ary_and(result, argv[i]);
}
return result;
}
Returns a new array containing each element in [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] Each element must correctly implement method Order from [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2] Returns a copy of Related: see Methods for Combining.
{} Sourcestatic VALUE
rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
{
VALUE sep;
if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
sep = rb_output_fs;
if (!NIL_P(sep)) {
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
}
}
return rb_ary_join(ary, sep);
}
Returns the new string formed by joining the string-converted elements of $, # => nil %w[].join # => "" %w[foo].join # => "foo" a = %w[foo bar baz] # => ["foo", "bar", "baz"] a.join # => "foobarbaz" a.join('|') # => "foo|bar|baz" a.join(' :|: ') # => "foo :|: bar :|: baz" Flattens and joins nested arrays: [:foo, [:bar, [:baz, :bat]]].join # => "foobarbazbat" Related: see Methods for Converting.
{} Sourcestatic VALUE
rb_ary_keep_if(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_select_bang(ary);
return ary;
}
With a block given, calls the block with each element of a = [:foo, 'bar', 2, :bam] a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam] With no block given, returns a new Related: see Methods for Deleting. {} Source# File array.rb, line 166 def last n = unspecified = true if Primitive.mandatory_only? Primitive.attr! :leaf Primitive.cexpr! %q{ ary_last(self) } else if unspecified Primitive.cexpr! %q{ ary_last(self) } else Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LEN(n), ARY_TAKE_LAST) } end end end Returns elements from With no argument given, returns the last element, or a = [:foo, 'bar', 2] a.last # => 2 a # => [:foo, "bar", 2] [].last # => nil With non-negative integer argument a = [:foo, 'bar', 2] a.last(2) # => ["bar", 2] a.last(50) # => [:foo, "bar", 2] a.last(0) # => [] [].last(3) # => [] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_length(VALUE ary)
{
rb_len_t len = RARRAY_LEN(ary);
return LEN2NUM(len);
}
Returns the count of elements in [0, 1, 2].length # => 3 [].length # => 0 Related: see Methods for Querying.
Also aliased as: size
With a block given, calls the block with each element of a = [:foo, 'bar', 2] a1 = a.map {|element| element.class } a1 # => [Symbol, String, Integer] With no block given, returns a new Related:
Alias for: collect
With a block given, calls the block with each element of a = [:foo, 'bar', 2] a.map! { |element| element.class } # => [Symbol, String, Integer] With no block given, returns a new Related:
Alias for: collect!
{} Sourcestatic VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
VALUE result = Qundef, v;
VALUE num;
rb_len_t i;
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 1, 1);
const rb_len_t n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
result = v;
}
}
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_max_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_max_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_max_opt_float(ary, 1, result);
}
else {
return ary_max_generic(ary, 1, result);
}
}
}
if (UNDEF_P(result)) return Qnil;
return result;
}
Returns one of the following:
Does not modify With no block given, each element in With no argument and no block, returns the element in [1, 0, 3, 2].max # => 3 With non-negative numeric argument [1, 0, 3, 2].max(3) # => [3, 2, 1] [1, 0, 3, 2].max(3.0) # => [3, 2, 1] [1, 0, 3, 2].max(9) # => [3, 2, 1, 0] [1, 0, 3, 2].max(0) # => [] With a block given, the block must return a numeric. With a block and no argument, calls the block ['0', '', '000', '00'].max {|a, b| a.size <=> b.size } # => "000" With non-negative numeric argument ['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
{
VALUE result = Qundef, v;
VALUE num;
rb_len_t i;
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 0, 1);
const rb_len_t n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
result = v;
}
}
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_min_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_min_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_min_opt_float(ary, 1, result);
}
else {
return ary_min_generic(ary, 1, result);
}
}
}
if (UNDEF_P(result)) return Qnil;
return result;
}
Returns one of the following:
Does not modify With no block given, each element in With no argument and no block, returns the element in [1, 0, 3, 2].min # => 0 With non-negative numeric argument [1, 0, 3, 2].min(3) # => [0, 1, 2] [1, 0, 3, 2].min(3.0) # => [0, 1, 2] [1, 0, 3, 2].min(9) # => [0, 1, 2, 3] [1, 0, 3, 2].min(0) # => [] With a block given, the block must return a numeric. With a block and no argument, calls the block ['0', '', '000', '00'].min {|a, b| a.size <=> b.size } # => "" With non-negative numeric argument ['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size } # => ["", "0"] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_minmax(VALUE ary)
{
if (rb_block_given_p()) {
return rb_call_super(0, NULL);
}
return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
}
Returns a 2-element array containing the minimum-valued and maximum-valued elements from With no block given, the minimum and maximum values are determined using method [1, 0, 3, 2].minmax # => [0, 3] With a block given, the block must return a numeric; the block is called ['0', '', '000', '00'].minmax {|a, b| a.size <=> b.size } # => ["", "000"] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
{
rb_len_t i, len = RARRAY_LEN(ary);
rb_check_arity(argc, 0, 1);
if (!len) return Qtrue;
if (argc) {
if (rb_block_given_p()) {
rb_warn("given block not used");
}
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
}
}
else if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) {
if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
}
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
}
}
return Qtrue;
}
Returns With no block given and no argument, returns [nil, false].none? # => true [nil, 0, false].none? # => false [].none? # => true With argument ['food', 'drink'].none?(/bar/) # => true ['food', 'drink'].none?(/foo/) # => false [].none?(/foo/) # => true [0, 1, 2].none?(3) # => true [0, 1, 2].none?(1) # => false With a block given, calls the block with each element in [0, 1, 2].none? {|element| element > 3 } # => true [0, 1, 2].none? {|element| element > 1 } # => false Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
{
rb_len_t i, len = RARRAY_LEN(ary);
VALUE result = Qfalse;
rb_check_arity(argc, 0, 1);
if (!len) return Qfalse;
if (argc) {
if (rb_block_given_p()) {
rb_warn("given block not used");
}
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
if (result) return Qfalse;
result = Qtrue;
}
}
}
else if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) {
if (RTEST(RARRAY_AREF(ary, i))) {
if (result) return Qfalse;
result = Qtrue;
}
}
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
if (result) return Qfalse;
result = Qtrue;
}
}
}
return result;
}
Returns With no block given and no argument, returns [nil, 0].one? # => true [0, 0].one? # => false [nil, nil].one? # => false [].one? # => false With a block given, calls the block with each element in [0, 1, 2].one? {|element| element > 0 } # => false [0, 1, 2].one? {|element| element > 1 } # => true [0, 1, 2].one? {|element| element > 2 } # => false With argument [0, 1, 2].one?(0) # => true [0, 0, 1].one?(0) # => false [1, 1, 2].one?(0) # => false ['food', 'drink'].one?(/bar/) # => false ['food', 'drink'].one?(/foo/) # => true [].one?(/foo/) # => false Related: see Methods for Querying. # File pack.rb, line 7 def pack(fmt, buffer: nil) Primitive.pack_pack(fmt, buffer) end Formats each element in
{} Sourcestatic VALUE
rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
{
rb_len_t r, i;
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
r = NUM2LEN(argv[0]); /* Permutation size from argument */
}
else {
r = RARRAY_LEN(ary);
}
rb_len_t n = RARRAY_LEN(ary);
if (r < 0 || n < r) {
/* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else { /* this is the general case */
volatile VALUE t0;
rb_len_t *p = ALLOCV_N(rb_len_t, t0, r+roomof(n, sizeof(rb_len_t)));
char *used = (char*)(p + r);
VALUE ary0 = ary_make_hidden_shared_copy(ary); /* private defensive copy of ary */
MEMZERO(used, char, n); /* initialize array */
permute0(n, r, p, used, ary0); /* compute and yield permutations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
Iterates over permutations of the elements of With a block and an in-range positive integer argument a = [0, 1, 2] perms = [] a.permutation(1) {|perm| perms.push(perm) } perms # => [[0], [1], [2]] perms = [] a.permutation(2) {|perm| perms.push(perm) } perms # => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]] perms = [] a.permutation(3) {|perm| perms.push(perm) } perms # => [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]] When perms = [] a.permutation(0) {|perm| perms.push(perm) } perms # => [[]] When a.permutation(-1) {|permutation| fail 'Cannot happen' } a.permutation(4) {|permutation| fail 'Cannot happen' } With no block given, returns a new Related: Methods for Iterating. {} Sourcestatic VALUE
rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
{
VALUE result;
if (argc == 0) {
return rb_ary_pop(ary);
}
rb_ary_modify_check(ary);
result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
ary_verify(ary);
return result;
}
Removes and returns trailing elements of With no argument given, removes and returns the last element, if available; otherwise returns a = [:foo, 'bar', 2] a.pop # => 2 a # => [:foo, "bar"] [].pop # => nil With non-negative integer argument a = [:foo, 'bar', 2] a.pop(2) # => ["bar", 2] a # => [:foo] a = [:foo, 'bar', 2] a.pop(50) # => [:foo, "bar", 2] a # => [] Related:
Prepends the given a = [:foo, 'bar', 2] a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] Related:
Alias for: unshift
{} Sourcestatic VALUE
rb_ary_product(int argc, VALUE *argv, VALUE ary)
{
int n = argc+1; /* How many arrays we're operating on */
volatile VALUE t0 = rb_ary_hidden_new(n);
volatile VALUE t1 = Qundef;
VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
rb_len_t *counters = ALLOCV_N(rb_len_t, t1, n); /* The current position in each one */
VALUE result = Qnil; /* The array we'll be returning, when no block given */
rb_len_t i,j;
rb_len_t resultlen = 1;
/* initialize the arrays of arrays */
ARY_SET_LEN(t0, n);
arrays[0] = ary;
for (i = 1; i < n; i++) arrays[i] = Qnil;
for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
/* initialize the counters for the arrays */
for (i = 0; i < n; i++) counters[i] = 0;
/* Otherwise, allocate and fill in an array of results */
if (rb_block_given_p()) {
/* Make defensive copies of arrays; exit if any is empty */
for (i = 0; i < n; i++) {
if (RARRAY_LEN(arrays[i]) == 0) goto done;
arrays[i] = ary_make_shared_copy(arrays[i]);
}
}
else {
/* Compute the length of the result array; return [] if any is empty */
for (i = 0; i < n; i++) {
rb_len_t k = RARRAY_LEN(arrays[i]);
if (k == 0) {
result = rb_ary_new2(0);
goto done;
}
if (MUL_OVERFLOW_SIGNED_INTEGER_P(resultlen, k, RB_LEN_MIN, RB_LEN_MAX))
rb_raise(rb_eRangeError, "too big to product");
resultlen *= k;
}
result = rb_ary_new2(resultlen);
}
for (;;) {
int m;
/* fill in one subarray */
VALUE subarray = rb_ary_new2(n);
for (j = 0; j < n; j++) {
rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
}
/* put it on the result array */
if (NIL_P(result)) {
FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
rb_yield(subarray);
if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
rb_raise(rb_eRuntimeError, "product reentered");
}
else {
FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
}
}
else {
rb_ary_push(result, subarray);
}
/*
* Increment the last counter. If it overflows, reset to 0
* and increment the one before it.
*/
m = n-1;
counters[m]++;
while (counters[m] == RARRAY_LEN(arrays[m])) {
counters[m] = 0;
/* If the first counter overflows, we are done */
if (--m < 0) goto done;
counters[m]++;
}
}
done:
ALLOCV_END(t1);
return NIL_P(result) ? ary : result;
}
Computes all combinations of elements from all the arrays, including both
With no block given, returns the combinations as an array of arrays: p = [0, 1].product([2, 3]) # => [[0, 2], [0, 3], [1, 2], [1, 3]] p.size # => 4 p = [0, 1].product([2, 3], [4, 5]) # => [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3,... p.size # => 8 If [].product([2, 3], [4, 5]) # => [] [0, 1].product([2, 3], []) # => [] If no argument is given, returns an array of 1-element arrays, each containing an element of [0, 1, 2].product # => [[0], [1], [2]] With a block given, calls the block with each combination; returns p = [] [0, 1].product([2, 3]) {|combination| p.push(combination) } p # => [[0, 2], [0, 3], [1, 2], [1, 3]] If [].product([2, 3], [4, 5]) {|combination| fail 'Cannot happen' } # => [] [0, 1].product([2, 3], []) {|combination| fail 'Cannot happen' } # => [0, 1] If no argument is given, calls the block with each element of p = [] [0, 1].product {|combination| p.push(combination) } p # => [[0], [1]] Related: see Methods for Combining.
{} Sourcestatic VALUE
rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
{
return rb_ary_cat(ary, argv, argc);
}
Appends each argument in a = [:foo, 'bar', 2] # => [:foo, "bar", 2] a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] Appends each argument as a single element, even if it is another array: a = [:foo, 'bar', 2] # => [:foo, "bar", 2] a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] Related: see Methods for Assigning.
Also aliased as: append
{} SourceVALUE
rb_ary_rassoc(VALUE ary, VALUE value)
{
rb_len_t i;
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = rb_check_array_type(RARRAY_AREF(ary, i));
if (RB_TYPE_P(v, T_ARRAY) &&
RARRAY_LEN(v) > 1 &&
rb_equal(RARRAY_AREF(v, 1), value))
return v;
}
return Qnil;
}
Returns the first element a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] a.rassoc(4) # => [2, 4] a.rassoc(5) # => [4, 5, 6] Returns Related: static VALUE
rb_ary_reject(VALUE ary)
{
VALUE rejected_ary;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rejected_ary = rb_ary_new();
ary_reject(ary, rejected_ary);
return rejected_ary;
}
With a block given, returns a new array whose elements are all those from a = [:foo, 'bar', 2, 'bat'] a1 = a.reject {|element| element.to_s.start_with?('b') } a1 # => [:foo, 2] With no block given, returns a new Related: Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_reject_bang(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
return ary_reject_bang(ary);
}
With a block given, calls the block with each element of Returns a = [:foo, 'bar', 2, 'bat'] a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2] Returns With no block given, returns a new Related: see Methods for Deleting.
{} Sourcestatic VALUE
rb_ary_repeated_combination(VALUE ary, VALUE num)
{
rb_len_t n, i, len;
n = NUM2LEN(num); /* Combination size from argument */
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
len = RARRAY_LEN(ary);
if (n < 0) {
/* yield nothing */
}
else if (n == 0) {
rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else if (len == 0) {
/* yield nothing */
}
else {
volatile VALUE t0;
rb_len_t *p = ALLOCV_N(rb_len_t, t0, n);
VALUE ary0 = ary_make_hidden_shared_copy(ary); /* private defensive copy of ary */
rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
With a block given, calls the block with each repeated combination of length If a positive integer argument Examples:
If If [0, 1, 2].repeated_combination(-1) {|combination| fail 'Cannot happen' } With no block given, returns a new Related: see Methods for Combining.
{} Sourcestatic VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
{
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
rb_len_t r = NUM2LEN(num); /* Permutation size from argument */
rb_len_t n = RARRAY_LEN(ary);
if (r < 0) {
/* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
for (rb_len_t i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else { /* this is the general case */
volatile VALUE t0;
rb_len_t *p = ALLOCV_N(rb_len_t, t0, r);
VALUE ary0 = ary_make_hidden_shared_copy(ary); /* private defensive copy of ary */
rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
With a block given, calls the block with each repeated permutation of length If a positive integer argument Examples:
If If [0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' } With no block given, returns a new Related: see Methods for Combining.
Replaces the elements of a = ['a', 'b', 'c'] # => ["a", "b", "c"] a.replace(['d', 'e']) # => ["d", "e"] Related: see Methods for Assigning.
Alias for: initialize_copy
{} Sourcestatic VALUE
rb_ary_reverse_m(VALUE ary)
{
rb_len_t len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);
if (len > 0) {
const VALUE *p1 = RARRAY_CONST_PTR(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
rb_gc_writebarrier_remember(dup);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}
Returns a new array containing the elements of [0, 1, 2].reverse # => [2, 1, 0] Related: see Methods for Combining.
{} Sourcestatic VALUE
rb_ary_reverse_bang(VALUE ary)
{
return rb_ary_reverse(ary);
}
Reverses the order of the elements of a = [0, 1, 2] a.reverse! # => [2, 1, 0] a # => [2, 1, 0] Related: see Methods for Assigning.
{} Sourcestatic VALUE
rb_ary_reverse_each(VALUE ary)
{
rb_len_t len;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
len = RARRAY_LEN(ary);
while (len--) {
rb_len_t nlen;
rb_yield(RARRAY_AREF(ary, len));
nlen = RARRAY_LEN(ary);
if (nlen < len) {
len = nlen;
}
}
return ary;
}
When a block given, iterates backwards over the elements of a = [] [0, 1, 2].reverse_each {|element| a.push(element) } a # => [2, 1, 0] Allows the array to be modified during iteration: a = ['a', 'b', 'c'] a.reverse_each {|element| a.clear if element.start_with?('b') } a # => [] When no block given, returns a new Related: see Methods for Iterating.
{} Sourcestatic VALUE
rb_ary_rfind(int argc, VALUE *argv, VALUE ary)
{
VALUE if_none;
rb_len_t len, idx;
if_none = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
RETURN_ENUMERATOR(ary, argc, argv);
idx = RARRAY_LEN(ary);
while (idx--) {
VALUE elem = RARRAY_AREF(ary, idx);
if (RTEST(rb_yield(elem))) {
return elem;
}
len = RARRAY_LEN(ary);
idx = (idx >= len) ? len : idx;
}
if (!NIL_P(if_none)) {
return rb_funcallv(if_none, idCall, 0, 0);
}
return Qnil;
}
Returns the last element for which the block returns a truthy value. With a block given, calls the block with successive elements of the array in reverse order; returns the first element for which the block returns a truthy value: [1, 2, 3, 4, 5, 6].rfind {|element| element < 5} # => 4 If no such element is found, calls [1, 2, 3, 4].rfind(proc {0}) {|element| element < -2} # => 0 With no block given, returns an
{} Sourcestatic VALUE
rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
{
VALUE val;
rb_len_t i = RARRAY_LEN(ary), len;
if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
while (i--) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
return LEN2NUM(i);
if (i > (len = RARRAY_LEN(ary))) {
i = len;
}
}
return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
while (i--) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LEN2NUM(i);
}
if (i > RARRAY_LEN(ary)) {
break;
}
}
return Qnil;
}
Returns the index of the last element for which With argument a = [:foo, 'bar', 2, 'bar'] a.rindex('bar') # => 3 Returns With a block given, calls the block with each successive element; returns the index of the last element for which the block returns a truthy value: a = [:foo, 'bar', 2, 'bar'] a.rindex {|element| element == 'bar' } # => 3 Returns When neither an argument nor a block is given, returns a new Related: see Methods for Querying.
{} Sourcestatic VALUE
rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
{
VALUE rotated;
const VALUE *ptr;
rb_len_t len;
rb_len_t cnt = (rb_check_arity(argc, 0, 1) ? NUM2LEN(argv[0]) : 1);
len = RARRAY_LEN(ary);
rotated = rb_ary_new2(len);
if (len > 0) {
cnt = rotate_count(cnt, len);
ptr = RARRAY_CONST_PTR(ary);
len -= cnt;
ary_memcpy(rotated, 0, len, ptr + cnt);
ary_memcpy(rotated, len, cnt, ptr);
}
ARY_SET_LEN(rotated, RARRAY_LEN(ary));
return rotated;
}
Returns a new array formed from With non-negative numeric [0, 1, 2, 3].rotate(2) # => [2, 3, 0, 1] [0, 1, 2, 3].rotate(2.1) # => [2, 3, 0, 1] If [0, 1, 2, 3].rotate(22) # => [2, 3, 0, 1] With a [0, 1, 2, 3].rotate(0) # => [0, 1, 2, 3] With negative numeric [0, 1, 2, 3].rotate(-1) # => [3, 0, 1, 2] If [0, 1, 2, 3].rotate(-21) # => [3, 0, 1, 2] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
{
rb_len_t n = (rb_check_arity(argc, 0, 1) ? NUM2LEN(argv[0]) : 1);
rb_ary_rotate(ary, n);
return ary;
}
Rotates With non-negative numeric [0, 1, 2, 3].rotate!(2) # => [2, 3, 0, 1] [0, 1, 2, 3].rotate!(2.1) # => [2, 3, 0, 1] If [0, 1, 2, 3].rotate!(21) # => [1, 2, 3, 0] If [0, 1, 2, 3].rotate!(0) # => [0, 1, 2, 3] With a negative numeric [0, 1, 2, 3].rotate!(-1) # => [3, 0, 1, 2] If [0, 1, 2, 3].rotate!(-21) # => [3, 0, 1, 2] Related: see Methods for Assigning.
{} Source# File array.rb, line 95 def sample(n = (single = true), random: Random) if Primitive.mandatory_only? Primitive.ary_sample0 elsif single Primitive.ary_sample1(random) else Primitive.ary_sample(random, n) end end Returns random elements from With no argument a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a.sample # => 3 a.sample # => 8 Returns [].sample # => nil With a non-negative numeric argument a.sample(3) # => [8, 9, 2] a.sample(6) # => [9, 6, 0, 3, 1, 4] The order of the result array is unrelated to the order of Returns a new empty array if [].sample(4) # => [] May return duplicates in a = [1, 1, 1, 2, 2, 3] a.sample(a.size) # => [1, 1, 3, 2, 1, 2] Returns no more than a.sample(50) # => [6, 4, 1, 8, 5, 9, 0, 2, 3, 7] The object given with the keyword argument a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a.sample(random: Random.new(1)) # => 6 a.sample(4, random: Random.new(1)) # => [6, 10, 9, 2] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_select(VALUE ary)
{
VALUE result;
rb_len_t i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
rb_ary_push(result, rb_ary_elt(ary, i));
}
}
return result;
}
With a block given, calls the block with each element of a = [:foo, 'bar', 2, :bam] a.select {|element| element.to_s.start_with?('b') } # => ["bar", :bam] With no block given, returns a new Related: see Methods for Fetching.
Also aliased as: filter
{} Sourcestatic VALUE
rb_ary_select_bang(VALUE ary)
{
struct select_bang_arg args;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
args.ary = ary;
args.len[0] = args.len[1] = 0;
return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
}
With a block given, calls the block with each element of Returns a = [:foo, 'bar', 2, :bam] a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam] Returns With no block given, returns a new Related: see Methods for Deleting.
Also aliased as: filter!
{} Source# File lib/shellwords.rb, line 251 def shelljoin Shellwords.join(self) end Builds a command line string from an argument list See {} Sourcestatic VALUE
rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
{
VALUE result;
rb_len_t n;
if (argc == 0) {
return rb_ary_shift(ary);
}
rb_ary_modify_check(ary);
result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
n = RARRAY_LEN(result);
rb_ary_behead(ary,n);
return result;
}
Removes and returns leading elements from With no argument, removes and returns one element, if available, or a = [0, 1, 2, 3] a.shift # => 0 a # => [1, 2, 3] [].shift # => nil With non-negative numeric argument a = [0, 1, 2, 3] a.shift(2) # => [0, 1] a # => [2, 3] a.shift(1.1) # => [2] a # => [3] a.shift(0) # => [] a # => [3] If a = [0, 1, 2, 3] a.shift(50) # => [0, 1, 2, 3] a # => [] If Related: see Methods for Deleting.
{} Source# File array.rb, line 45 def shuffle(random: Random) Primitive.rb_ary_shuffle(random) end Returns a new array containing all elements from a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a.shuffle # => [0, 8, 1, 9, 6, 3, 4, 7, 2, 5] a.shuffle # => [8, 9, 0, 5, 1, 2, 6, 4, 7, 3] Duplicate elements are included: a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] a.shuffle # => [1, 0, 1, 1, 0, 0, 1, 0, 0, 1] a.shuffle # => [1, 1, 0, 0, 0, 1, 1, 0, 0, 1] The object given with the keyword argument Related: see Methods for Fetching.
{} Source# File array.rb, line 22 def shuffle!(random: Random) Primitive.rb_ary_shuffle_bang(random) end Shuffles all elements in a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a.shuffle! # => [5, 3, 8, 7, 6, 1, 9, 4, 2, 0] a.shuffle! # => [9, 4, 0, 6, 2, 8, 1, 5, 3, 7] Duplicate elements are included: a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] a.shuffle! # => [1, 0, 0, 1, 1, 0, 1, 0, 0, 1] a.shuffle! # => [0, 1, 0, 1, 1, 0, 1, 0, 1, 0] The object given with the keyword argument Related: see Methods for Assigning.
Returns the count of elements in [0, 1, 2].length # => 3 [].length # => 0 Related: see Methods for Querying.
Alias for: length
Alias for: []
static VALUE
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
{
VALUE arg1;
rb_len_t pos, len;
rb_ary_modify_check(ary);
rb_check_arity(argc, 1, 2);
arg1 = argv[0];
if (argc == 2) {
pos = NUM2LEN(argv[0]);
len = NUM2LEN(argv[1]);
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
}
if (!FIXNUM_P(arg1)) {
switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
case Qtrue:
/* valid range */
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
case Qnil:
/* invalid range */
return Qnil;
default:
/* not a range */
break;
}
}
return rb_ary_delete_at(ary, NUM2LEN(arg1));
}
Removes and returns elements from With numeric argument a = ['a', 'b', 'c', 'd'] a.slice!(2) # => "c" a # => ["a", "b", "d"] a.slice!(2.1) # => "d" a # => ["a", "b"] If a = ['a', 'b', 'c', 'd'] a.slice!(-2) # => "c" a # => ["a", "b", "d"] If With numeric arguments a = ['a', 'b', 'c', 'd'] a.slice!(1, 2) # => ["b", "c"] a # => ["a", "d"] a.slice!(0.1, 1.1) # => ["a"] a # => ["d"] If a = ['a', 'b', 'c', 'd'] a.slice!(-2, 1) # => ["c"] a # => ["a", "b", "d"] If a = ['a', 'b', 'c', 'd'] a.slice!(5, 1) # => nil a.slice!(-5, 1) # => nil If a = ['a', 'b', 'c', 'd'] a.slice!(2, 50) # => ["c", "d"] a # => ["a", "b"] If If With a = ['a', 'b', 'c', 'd'] a.slice!(1..2) # => ["b", "c"] a # => ["a", "d"] If a = ['a', 'b', 'c', 'd'] a.slice!(4..5) # => [] If a = ['a', 'b', 'c', 'd'] a.slice!(5..6) # => nil If a = ['a', 'b', 'c', 'd'] a.slice!(-2..2) # => ["c"] If a = ['a', 'b', 'c', 'd'] a.slice!(0..-2) # => ["a", "b", "c"] Related: see Methods for Deleting.
{} SourceVALUE
rb_ary_sort(VALUE ary)
{
ary = rb_ary_dup(ary);
rb_ary_sort_bang(ary);
return ary;
}
Returns a new array containing the elements of With no block given, compares elements using operator [0, 2, 3, 1].sort # => [0, 1, 2, 3] With a block given, calls the block with each combination of pairs of elements from
Example: a = [3, 2, 0, 1] a.sort {|a, b| a <=> b } # => [0, 1, 2, 3] a.sort {|a, b| b <=> a } # => [3, 2, 1, 0] When the block returns zero, the order for See an example in Related: see Methods for Fetching.
{} SourceVALUE
rb_ary_sort_bang(VALUE ary)
{
rb_ary_modify(ary);
RUBY_ASSERT(!ARY_SHARED_P(ary));
if (RARRAY_LEN(ary) > 1) {
VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
struct ary_sort_data data;
rb_len_t len = RARRAY_LEN(ary);
RBASIC_CLEAR_CLASS(tmp);
data.ary = tmp;
data.receiver = ary;
RARRAY_PTR_USE(tmp, ptr, {
ruby_qsort(ptr, len, sizeof(VALUE),
rb_block_given_p()?sort_1:sort_2, &data);
}); /* WB: no new reference */
rb_ary_modify(ary);
if (ARY_EMBED_P(tmp)) {
if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
}
ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
}
else {
if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
FL_UNSET_SHARED(ary);
ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
}
else {
RUBY_ASSERT(!ARY_SHARED_P(tmp));
if (ARY_EMBED_P(ary)) {
FL_UNSET_EMBED(ary);
}
else if (ARY_SHARED_P(ary)) {
/* ary might be destructively operated in the given block */
rb_ary_unshare(ary);
}
else {
ary_heap_free(ary);
}
ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
ARY_SET_HEAP_LEN(ary, len);
ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
}
/* tmp was lost ownership for the ptr */
FL_SET_EMBED(tmp);
ARY_SET_EMBED_LEN(tmp, 0);
OBJ_FREEZE(tmp);
}
/* tmp will be GC'ed. */
RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
}
ary_verify(ary);
return ary;
}
Like Related: see Methods for Assigning.
{} Sourcestatic VALUE
rb_ary_sort_by_bang(VALUE ary)
{
VALUE sorted;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
if (RARRAY_LEN(ary) > 1) {
sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
rb_ary_replace(ary, sorted);
}
return ary;
}
With a block given, sorts the elements of Calls the block with each successive element; sorts elements based on the values returned from the block: a = ['aaaa', 'bbb', 'cc', 'd'] a.sort_by! {|element| element.size } a # => ["d", "cc", "bbb", "aaaa"] For duplicate values returned by the block, the ordering is indeterminate, and may be unstable. With no block given, returns a new Related: see Methods for Assigning.
{} Sourcestatic VALUE
rb_ary_sum(int argc, VALUE *argv, VALUE ary)
{
VALUE e, v, r;
rb_len_t i;
long n;
int block_given;
v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));
block_given = rb_block_given_p();
if (RARRAY_LEN(ary) == 0)
return v;
n = 0;
r = Qundef;
bool init_is_float = RB_FLOAT_TYPE_P(v);
if (init_is_float) {
v = LONG2FIX(0);
}
else if (!RB_INTEGER_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
i = 0;
goto init_is_a_value;
}
for (i = 0; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (FIXNUM_P(e)) {
n += FIX2LONG(e); /* should not overflow long type */
if (!FIXABLE(n)) {
v = rb_big_plus(LONG2NUM(n), v);
n = 0;
}
}
else if (RB_BIGNUM_TYPE_P(e))
v = rb_big_plus(e, v);
else if (RB_TYPE_P(e, T_RATIONAL)) {
if (UNDEF_P(r))
r = e;
else
r = rb_rational_plus(r, e);
}
else
goto not_exact;
}
v = finish_exact_sum(n, r, v, argc!=0);
if (init_is_float) v = rb_float_plus(argv[0], v);
return v;
not_exact:
v = finish_exact_sum(n, r, v, i!=0);
if (init_is_float && !RB_FLOAT_TYPE_P(e)) {
v = rb_float_plus(argv[0], v);
goto has_some_value;
}
if (init_is_float || RB_FLOAT_TYPE_P(e)) {
/*
* Kahan-Babuska balancing compensated summation algorithm
* See https://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double f, c;
double x, t;
f = NUM2DBL(v);
c = 0.0;
if (init_is_float) {
x = RFLOAT_VALUE(argv[0]);
t = f + x;
f = t;
}
goto has_float_value;
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (RB_FLOAT_TYPE_P(e))
has_float_value:
x = RFLOAT_VALUE(e);
else if (FIXNUM_P(e))
x = FIX2LONG(e);
else if (RB_BIGNUM_TYPE_P(e))
x = rb_big2dbl(e);
else if (RB_TYPE_P(e, T_RATIONAL))
x = rb_num2dbl(e);
else
goto not_float;
if (isnan(f)) continue;
if (isnan(x)) {
f = x;
continue;
}
if (isinf(x)) {
if (isinf(f) && signbit(x) != signbit(f))
f = NAN;
else
f = x;
continue;
}
if (isinf(f)) continue;
t = f + x;
if (fabs(f) >= fabs(x))
c += ((f - t) + x);
else
c += ((x - t) + f);
f = t;
}
f += c;
return DBL2NUM(f);
not_float:
v = DBL2NUM(f);
}
goto has_some_value;
init_is_a_value:
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
has_some_value:
v = rb_funcall(v, idPLUS, 1, e);
}
return v;
}
With no block given, returns the sum of sum = init array.each {|element| sum += element } sum For example, Examples: [0, 1, 2, 3].sum # => 6 [0, 1, 2, 3].sum(100) # => 106 ['abc', 'def', 'ghi'].sum('jkl') # => "jklabcdefghi" [[:foo, :bar], ['foo', 'bar']].sum([2, 3]) # => [2, 3, :foo, :bar, "foo", "bar"] The # Raises TypeError: Array can't be coerced into Integer. [[:foo, :bar], ['foo', 'bar']].sum(2) With a block given, calls the block with each element of ['zero', 1, :two].sum('Coerced and concatenated: ') {|element| element.to_s } # => "Coerced and concatenated: zero1two" Notes:
{} Sourcestatic VALUE
rb_ary_take(VALUE obj, VALUE n)
{
rb_len_t len = NUM2LEN(n);
if (len < 0) {
rb_raise(rb_eArgError, "attempt to take negative size");
}
return rb_ary_subseq(obj, 0, len);
}
Returns a new array containing the first a = ['a', 'b', 'c', 'd'] a.take(2) # => ["a", "b"] a.take(2.1) # => ["a", "b"] a.take(50) # => ["a", "b", "c", "d"] a.take(0) # => [] Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_take_while(VALUE ary)
{
rb_len_t i;
RETURN_ENUMERATOR(ary, 0, 0);
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
}
return rb_ary_take(ary, LEN2NUM(i));
}
With a block given, calls the block with each successive element of a = [0, 1, 2, 3, 4, 5] a.take_while {|element| element < 3 } # => [0, 1, 2] a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5] a.take_while {|element| false } # => [] With no block given, returns a new Does not modify Related: see Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_to_a(VALUE ary)
{
if (rb_obj_class(ary) != rb_cArray) {
VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
rb_ary_replace(dup, ary);
return dup;
}
return ary;
}
When Otherwise, returns a new array containing the elements of class MyArray < Array; end my_a = MyArray.new(['foo', 'bar', 'two']) a = my_a.to_a a # => ["foo", "bar", "two"] a.class # => Array # Not MyArray. Related: see Methods for Converting.
{} Sourcestatic VALUE
rb_ary_to_ary_m(VALUE ary)
{
return ary;
}
Returns static VALUE
rb_ary_to_h(VALUE ary)
{
rb_len_t i;
VALUE hash = rb_hash_new_capa(RARRAY_LEN(ary));
int block_given = rb_block_given_p();
for (i=0; i<RARRAY_LEN(ary); i++) {
const VALUE e = rb_ary_elt(ary, i);
const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
const VALUE key_value_pair = rb_check_array_type(elt);
if (NIL_P(key_value_pair)) {
rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %"PRIdLEN" (expected array)",
rb_obj_class(elt), i);
}
if (RARRAY_LEN(key_value_pair) != 2) {
rb_raise(rb_eArgError, "wrong array length at %"PRIdLEN" (expected 2, was %"PRIdLEN")",
i, RARRAY_LEN(key_value_pair));
}
rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
}
return hash;
}
Returns a new hash formed from With no block given, each element of a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']] a.to_h # => {"foo" => "zero", "bar" => "one", "baz" => "two"} [].to_h # => {} With a block given, the block must return a 2-element array; calls the block with each element of a = ['foo', :bar, 1, [2, 3], {baz: 4}] a.to_h {|element| [element, element.class] } # => {"foo" => String, bar: Symbol, 1 => Integer, [2, 3] => Array, {baz: 4} => Hash} Related: see Methods for Converting.
Returns the new string formed by calling method a = [:foo, 'bar', 2] a.inspect # => "[:foo, \"bar\", 2]" Related: see Methods for Converting.
Alias for: inspect
static VALUE
rb_ary_transpose(VALUE ary)
{
rb_len_t elen = -1, alen, i, j;
VALUE tmp, result = 0;
alen = RARRAY_LEN(ary);
if (alen == 0) return rb_ary_dup(ary);
for (i=0; i<alen; i++) {
tmp = to_ary(rb_ary_elt(ary, i));
if (elen < 0) { /* first element */
elen = RARRAY_LEN(tmp);
result = rb_ary_new2(elen);
for (j=0; j<elen; j++) {
rb_ary_store(result, j, rb_ary_new2(alen));
}
}
else if (elen != RARRAY_LEN(tmp)) {
rb_raise(rb_eIndexError, "element size differs (%"PRIdLEN" should be %"PRIdLEN")",
RARRAY_LEN(tmp), elen);
}
for (j=0; j<elen; j++) {
rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
}
}
return result;
}
Returns a new array that is a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]] a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]] The elements of Related: see Methods for Converting.
{} Sourcestatic VALUE
rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
rb_len_t sum = RARRAY_LEN(ary);
for (int i = 0; i < argc; i++) {
argv[i] = to_ary(argv[i]);
sum += RARRAY_LEN(argv[i]);
}
if (sum <= SMALL_ARRAY_LEN) {
VALUE ary_union = rb_ary_new();
rb_ary_union(ary_union, ary);
for (int i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
return ary_union;
}
VALUE set = rb_obj_hide(rb_set_new_capa(sum));
rb_ary_union_set(set, ary);
for (int i = 0; i < argc; i++) rb_ary_union_set(set, argv[i]);
return rb_set_to_a(set);
}
Returns a new array that is the union of the elements of [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7] Removes duplicates (preserving the first found): [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3] Preserves order (preserving the position of the first found): [3, 2, 1, 0].union([5, 3], [4, 2]) # => [3, 2, 1, 0, 5, 4] With no arguments given, returns a copy of Related: see Methods for Combining. static VALUE
rb_ary_uniq(VALUE ary)
{
if (RARRAY_LEN(ary) <= 1) {
return rb_ary_dup(ary);
}
VALUE set = rb_obj_hide(rb_set_new_capa(RARRAY_LEN(ary)));
if (rb_block_given_p()) {
VALUE uniq = rb_ary_new_capa(RARRAY_LEN(ary));
for (rb_len_t i = 0; i < RARRAY_LEN(ary); i++) {
VALUE elt = rb_ary_elt(ary, i);
if (rb_set_add_no_check(set, rb_yield(elt)))
rb_ary_push(uniq, elt);
}
return uniq;
}
else {
rb_ary_union_set(set, ary);
return rb_set_to_a(set);
}
}
Returns a new array containing those elements from With no block given, identifies and omits duplicate elements using method a = [0, 0, 1, 1, 2, 2] a.uniq # => [0, 1, 2] With a block given, calls the block for each element; identifies and omits “duplicate” elements using method a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb'] a.uniq {|element| element.size } # => ["a", "aa", "aaa"] Related: Methods for Fetching.
{} Sourcestatic VALUE
rb_ary_uniq_bang(VALUE ary)
{
rb_ary_modify_check(ary);
if (RARRAY_LEN(ary) <= 1)
return Qnil;
if (rb_block_given_p()) {
VALUE set = rb_obj_hide(rb_set_new_capa(RARRAY_LEN(ary)));
VALUE uniq = rb_ary_new_capa(RARRAY_LEN(ary));
for (rb_len_t i = 0; i < RARRAY_LEN(ary); i++) {
VALUE elt = rb_ary_elt(ary, i);
if (rb_set_add_no_check(set, rb_yield(elt)))
rb_ary_push(uniq, elt);
}
if (RARRAY_LEN(ary) == RARRAY_LEN(uniq))
return Qnil;
rb_ary_replace(ary, uniq);
return ary;
}
VALUE set = ary_to_set(ary);
rb_len_t size = (rb_len_t)rb_set_size(set);
if (RARRAY_LEN(ary) == size) {
return Qnil;
}
rb_ary_modify_check(ary);
ARY_SET_LEN(ary, 0);
if (ARY_SHARED_P(ary)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
ary_resize_capa(ary, size);
rb_set_foreach(set, push_value_i, ary);
return ary;
}
Removes duplicate elements from With no block given, identifies and removes elements using method a = [0, 0, 1, 1, 2, 2] a.uniq! # => [0, 1, 2] a.uniq! # => nil With a block given, calls the block for each element; identifies and omits “duplicate” elements using method a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb'] a.uniq! {|element| element.size } # => ["a", "aa", "aaa"] a.uniq! {|element| element.size } # => nil Related: see Methods for Deleting.
{} SourceVALUE
rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
{
rb_len_t len = RARRAY_LEN(ary);
VALUE target_ary;
if (argc == 0) {
rb_ary_modify_check(ary);
return ary;
}
target_ary = ary_ensure_room_for_unshift(ary, argc);
ary_memcpy0(ary, 0, argc, argv, target_ary);
ARY_SET_LEN(ary, len + argc);
return ary;
}
Prepends the given a = [:foo, 'bar', 2] a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] Related:
Also aliased as: prepend
{} Sourcestatic VALUE
rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
{
rb_len_t 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;
}
Returns elements from The objects included in the returned array are the elements of 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 a = ['a', 'b', 'c', 'd'] a.values_at # => [] For each numeric specifier
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 a.values_at(4, -5) # => [nil, nil] For each
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.
{} Sourcestatic VALUE
rb_ary_zip(int argc, VALUE *argv, VALUE ary)
{
int i, j;
rb_len_t len = RARRAY_LEN(ary);
VALUE result = Qnil;
for (i=0; i<argc; i++) {
argv[i] = take_items(argv[i], len);
}
if (rb_block_given_p()) {
int arity = rb_block_arity();
if (arity > 1) {
VALUE work, *tmp;
tmp = ALLOCV_N(VALUE, work, argc+1);
for (i=0; i<RARRAY_LEN(ary); i++) {
tmp[0] = RARRAY_AREF(ary, i);
for (j=0; j<argc; j++) {
tmp[j+1] = rb_ary_elt(argv[j], i);
}
rb_yield_values2(argc+1, tmp);
}
if (work) ALLOCV_END(work);
}
else {
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE tmp = rb_ary_new2(argc+1);
rb_ary_push(tmp, RARRAY_AREF(ary, i));
for (j=0; j<argc; j++) {
rb_ary_push(tmp, rb_ary_elt(argv[j], i));
}
rb_yield(tmp);
}
}
}
else {
result = rb_ary_new_capa(len);
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE tmp = rb_ary_new_capa(argc+1);
rb_ary_push(tmp, RARRAY_AREF(ary, i));
for (j=0; j<argc; j++) {
rb_ary_push(tmp, rb_ary_elt(argv[j], i));
}
rb_ary_push(result, tmp);
}
}
return result;
}
With no block given, combines [0, 1].zip(['zero', 'one'], [:zero, :one]) # => [[0, "zero", :zero], [1, "one", :one]] Returned:
Example: a = [0, 1] zipped = a.zip(['zero', 'one'], [:zero, :one]) # => [[0, "zero", :zero], [1, "one", :one]] zipped.size # => 2 # Same size as a. zipped.first.size # => 3 # Size of other arrays plus 1. When the other arrays are all the same size as a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] d = a.zip(b, c) pp d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] When one of the other arrays is smaller than a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2] c = [:c0, :c1] d = a.zip(b, c) pp d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]] When one of the other arrays is larger than a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3, :b4] c = [:c0, :c1, :c2, :c3, :c4, :c5] d = a.zip(b, c) pp d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] With a block given, calls the block with each of the other arrays; returns d = [] a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] a.zip(b, c) {|sub_array| d.push(sub_array.reverse) } # => nil pp d # => [[:c0, :b0, :a0], [:c1, :b1, :a1], [:c2, :b2, :a2], [:c3, :b3, :a3]] For an object in other_arrays that is not actually an array, forms the “other array” as Related: see Methods for Converting. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |