diff options
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 888 |
1 files changed, 888 insertions, 0 deletions
@@ -214,6 +214,44 @@ rb_check_array_type(ary) static VALUE rb_ary_replace _((VALUE, VALUE)); +/* + * call-seq: + * Array.new(size=0, obj=nil) + * Array.new(array) + * Array.new(size) {|i| ...} + + * Returns a new array. In the first form, the new array is + * empty. In the second it is created with _size_ copies of _obj_ + * (that is, _size_ references to the same + * _obj_). The third form creates a copy of the array + * passed as a parameter (the array is generated by calling + * to_ary on the parameter). In the last form, an array + * of the given size is created. Each element in this array is + * calculated by passing the element's index to the given block and + * storing the return value. + * + * Array.new + * Array.new(2) + * Array.new(5, "A") + * + * # only one copy of the object is created + * a = Array.new(2, Hash.new) + * a[0]['cat'] = 'feline' + * a + * a[1]['cat'] = 'Felix' + * a + * + * # here multiple copies are created + * a = Array.new(2) { Hash.new } + * a[0]['cat'] = 'feline' + * a + * + * squares = Array.new(5) {|i| i*i} + * squares + * + * copy = Array.new(squares) + */ + static VALUE rb_ary_initialize(argc, argv, ary) int argc; @@ -270,6 +308,15 @@ rb_ary_initialize(argc, argv, ary) return ary; } + +/* +* Returns a new array populated with the given objects. +* +* Array.[]( 1, 'a', /^A/ ) +* Array[ 1, 'a', /^A/ ] +* [ 1, 'a', /^A/ ] +*/ + static VALUE rb_ary_s_create(argc, argv, klass) int argc; @@ -329,6 +376,19 @@ rb_ary_store(ary, idx, val) RARRAY(ary)->ptr[idx] = val; } +/* + * call-seq: + * array << obj => array + * + * Append---Pushes the given object on to the end of this array. This + * expression returns the array itself, so several appends + * may be chained together. + * + * [ 1, 2 ] << "c" << "d" << [ 3, 4 ] + * #=> [ 1, 2, "c", "d", [ 3, 4 ] ] + * + */ + VALUE rb_ary_push(ary, item) VALUE ary; @@ -338,6 +398,19 @@ rb_ary_push(ary, item) return ary; } +/* + * call-seq: + * array.push(obj, ... ) => array + * + * Append---Pushes the given object(s) on to the end of this array. This + * expression returns the array itself, so several appends + * may be chained together. + * + * a = [ "a", "b", "c" ] + * a.push("d", "e", "f") + * #=> ["a", "b", "c", "d", "e", "f"] + */ + static VALUE rb_ary_push_m(argc, argv, ary) int argc; @@ -350,6 +423,18 @@ rb_ary_push_m(argc, argv, ary) return ary; } +/* + * call-seq: + * array.pop => obj or nil + * + * Removes the last element from <i>self</i> and returns it, or + * <code>nil</code> if the array is empty. + * + * a = [ "a", "m", "z" ] + * a.pop #=> "z" + * a #=> ["a", "m"] + */ + VALUE rb_ary_pop(ary) VALUE ary; @@ -381,6 +466,19 @@ ary_make_shared(ary) } } +/* + * call-seq: + * array.shift => obj or nil + * + * Returns the first element of <i>self</i> and removes it (shifting all + * other elements down by one). Returns <code>nil</code> if the array + * is empty. + * + * args = [ "-m", "-q", "filename" ] + * args.shift #=> "-m" + * args #=> ["-q", "filename"] + */ + VALUE rb_ary_shift(ary) VALUE ary; @@ -420,6 +518,18 @@ rb_ary_unshift(ary, item) return ary; } +/* + * call-seq: + * array.unshift(obj, ...) => array + * + * Prepends objects to the front of <i>array</i>. + * other elements up one. + * + * a = [ "b", "c", "d" ] + * a.unshift("a") #=> ["a", "b", "c", "d"] + * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"] + */ + static VALUE rb_ary_unshift_m(argc, argv, ary) int argc; @@ -488,6 +598,40 @@ rb_ary_subseq(ary, beg, len) return ary2; } +/* + * call-seq: + * array[int] => obj or nil + * array[start, length] => an_array or nil + * array[range] => an_array or nil + * array.slice(int) => obj or nil + * array.slice(start, length) => an_array or nil + * array.slice(range) => an_array or nil + * + * Element Reference---Returns the element at index _int_, + * or returns a subarray starting at index _start_ and + * continuing for _length_ elements, or returns a subarray + * specified by _range_. + * Negative indices count backward from the end of the + * array (-1 is the last element). Returns nil if any indices + * are out of range unless the index equals the array size and a + * _length_ or _range_ parameter is given, in which case an + * empty array is returned. + * + * a = [ "a", "b", "c", "d", "e" ] + * a[2] + a[0] + a[1] #=> "cab" + * a[6] #=> nil + * a[1, 2] #=> [ "b", "c" ] + * a[1..3] #=> [ "b", "c", "d" ] + * a[4..7] #=> [ "e" ] + * a[6..10] #=> nil + * a[-3, 3] #=> [ "c", "d", "e" ] + * # special cases + * a[5] #=> nil + * a[5, 1] #=> [] + * a[5..10] #=> [] + * + */ + VALUE rb_ary_aref(argc, argv, ary) int argc; @@ -531,6 +675,21 @@ rb_ary_aref(argc, argv, ary) return rb_ary_entry(ary, NUM2LONG(arg)); } +/* + * call-seq: + * array.at(int) #=> obj or nil + * + * Returns the element at index int. A + * negative index counts from the end of _self_. Returns +nil+ + * if the index is out of range. See also Array.[]. + * (Array.at is slightly faster than Array.[], as it + * does not accept ranges and so on.) + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + static VALUE rb_ary_at(ary, pos) VALUE ary, pos; @@ -538,6 +697,17 @@ rb_ary_at(ary, pos) return rb_ary_entry(ary, NUM2LONG(pos)); } +/* + * call-seq: + * array.first => obj or nil + * + * Returns the first element of the array. If the array is empty, + * returns <code>nil</code>. + * + * a = [ "q", "r", "s", "t" ] + * a.first #=> "q" + */ + static VALUE rb_ary_first(argc, argv, ary) int argc; @@ -563,6 +733,17 @@ rb_ary_first(argc, argv, ary) } } +/* + * call-seq: + * array.last => obj or nil + * array.last(n) => an_array + * + * Returns the last element(s) of <i>self</i>. If the array is empty, + * the first form returns <code>nil</code>. + * + * [ "w", "x", "y", "z" ].last #=> "z" + */ + static VALUE rb_ary_last(argc, argv, ary) int argc; @@ -588,6 +769,26 @@ rb_ary_last(argc, argv, ary) } } +/* + * call-seq: + * array.fetch(index) => obj + * array.fetch(index, default ) => obj + * array.fetch(index) {|i| block } => obj + * + * Tries to return the element at position <i>index</i>. If the index + * lies outside the array, the first form throws an + * <code>IndexError</code> exception, the second form returns + * <i>default</i>, and the third form returns the value of invoking + * the block, passing in the index. Negative values of <i>idex</i> + * count from the end of the array. + * + * a = [ 11, 22, 33, 44 ] + * a.fetch(1) #=> 22 + * a.fetch(-1) #=> 44 + * a.fetch(4, 'cat') #=> "cat" + * a.fetch(4) { |i| i*i } #=> 16 + */ + static VALUE rb_ary_fetch(argc, argv, ary) int argc; @@ -618,6 +819,19 @@ rb_ary_fetch(argc, argv, ary) return RARRAY(ary)->ptr[idx]; } +/* + * call-seq: + * array.index(obj) => int or nil + * + * Returns the index of the first object in <i>self</i> such that is + * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if + * no match is found. + * + * a = [ "a", "b", "c" ] + * a.index("b") #=> 1 + * a.index("z") #=> nil + */ + static VALUE rb_ary_index(ary, val) VALUE ary; @@ -632,6 +846,19 @@ rb_ary_index(ary, val) return Qnil; } +/* + * call-seq: + * array.rindex(obj) => int or nil + * + * Returns the index of the last object in <i>arr</i> + * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if + * no match is found. + * + * a = [ "a", "b", "b", "b", "c" ] + * a.rindex("b") #=> 3 + * a.rindex("z") #=> nil + */ + static VALUE rb_ary_rindex(ary, val) VALUE ary; @@ -646,6 +873,14 @@ rb_ary_rindex(ary, val) return Qnil; } +/* + * call-seq: + * array.indexes( i1, i2, ... iN ) => an_array + * array.indices( i1, i2, ... iN ) => an_array + * + * Deprecated; use <code>Array#select</code>. + */ + static VALUE rb_ary_indexes(argc, argv, ary) int argc; @@ -742,6 +977,34 @@ rb_ary_update(ary, beg, len, rpl) } } +/* + * call-seq: + * array[int] = obj => obj + * array[start, length] = an_array => an_array + * array[range] = an_array => an_array + * + * Element Assignment---Sets the element at index _int_, + * or replaces a subarray starting at index _start_ and + * continuing for _length_ elements, or replaces a subarray + * specified by _range_. If _int_ is greater than + * the current capacity of the array, the array grows + * automatically. A negative _int_ will count backward + * from the end of the array. Inserts elements if _length_ is + * zero. If _an_array is +nil+, deletes elements from _self_. + * An +IndexError+ is raised if a + * negative index points past the beginning of the array. See also + * Array.push, and Array.unshift. + * + * a = Array.new + * a[4] = "4"; + * a[0, 3] = [ 'a', 'b', 'c' ] + * a[1..2] = [ 1, 2 ]; + * a[0, 2] = "?"; + * a[0..2] = "A"; + * a[-1] = "Z"; + * a[1..-1] = nil; + */ + static VALUE rb_ary_aset(argc, argv, ary) int argc; @@ -782,6 +1045,18 @@ fixnum: return argv[1]; } +/* + * call-seq: + * array.insert(index, obj...) => array + * + * Inserts the given values before the element with the given index + * (which may be negative). + * + * a = %w{ a b c d } + * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"] + * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"] + */ + static VALUE rb_ary_insert(argc, argv, ary) int argc; @@ -806,6 +1081,21 @@ rb_ary_insert(argc, argv, ary) return ary; } +/* + * call-seq: + * array.each {|item| block } => array + * + * Calls <i>block</i> once for each element in <i>self</i>, passing that + * element as a parameter. + * + * a = [ "a", "b", "c" ] + * a.each {|x| print x, " -- " } + * + * produces: + * + * a -- b -- c -- + */ + VALUE rb_ary_each(ary) VALUE ary; @@ -818,6 +1108,21 @@ rb_ary_each(ary) return ary; } +/* + * call-seq: + * array.each_index {|index| block } => array + * + * Same as <code>Array#each</code>, but passes the index of the element + * instead of the element itself. + * + * a = [ "a", "b", "c" ] + * a.each_index {|x| print x, " -- " } + * + * produces: + * + * 0 -- 1 -- 2 -- + */ + static VALUE rb_ary_each_index(ary) VALUE ary; @@ -830,6 +1135,21 @@ rb_ary_each_index(ary) return ary; } +/* + * call-seq: + * array.reverse_each {|item| block } + * + * Same as <code>Array#each</code>, but traverses <i>self</i> in reverse + * order. + * + * a = [ "a", "b", "c" ] + * a.reverse_each {|x| print x, " " } + * + * produces: + * + * c b a + */ + static VALUE rb_ary_reverse_each(ary) VALUE ary; @@ -845,6 +1165,15 @@ rb_ary_reverse_each(ary) return ary; } +/* + * call-seq: + * array.length -> int + * + * Returns the number of elements in <i>self</i>. May be zero. + * + * [ 1, 2, 3, 4, 5 ].length #=> 5 + */ + static VALUE rb_ary_length(ary) VALUE ary; @@ -852,6 +1181,15 @@ rb_ary_length(ary) return LONG2NUM(RARRAY(ary)->len); } +/* + * call-seq: + * array.empty? => true or false + * + * Returns <code>true</code> if <i>self</i> array contains no elements. + * + * [].empty? #=> true + */ + static VALUE rb_ary_empty_p(ary) VALUE ary; @@ -933,6 +1271,17 @@ rb_ary_join(ary, sep) return result; } +/* + * call-seq: + * array.join(sep=$,) => str + * + * Returns a string created by converting each element of the array to + * a string, separated by <i>sep</i>. + * + * [ "a", "b", "c" ].join #=> "abc" + * [ "a", "b", "c" ].join("-") #=> "a-b-c" + */ + static VALUE rb_ary_join_m(argc, argv, ary) int argc; @@ -947,6 +1296,16 @@ rb_ary_join_m(argc, argv, ary) return rb_ary_join(ary, sep); } +/* + * call-seq: + * array.to_s -> string + * + * Returns _self_<code>.join</code>. + * + * [ "a", "e", "i", "o" ].to_s #=> "aeio" + * + */ + VALUE rb_ary_to_s(ary) VALUE ary; @@ -1067,6 +1426,14 @@ rb_ary_inspect(ary) return rb_protect_inspect(inspect_ary, ary, 0); } +/* + * call-seq: + * array.to_a -> array + * + * Returns _self_. If called on a subclass of Array, converts + * the receiver to an Array object. + */ + static VALUE rb_ary_to_a(ary) VALUE ary; @@ -1079,6 +1446,13 @@ rb_ary_to_a(ary) return ary; } +/* + * call-seq: + * array.to_ary -> array + * + * Returns _self_. + */ + static VALUE rb_ary_to_ary_m(ary) VALUE ary; @@ -1107,6 +1481,17 @@ rb_ary_reverse(ary) return ary; } +/* + * call-seq: + * array.reverse! => array + * + * Reverses _self_ in place. + * + * a = [ "a", "b", "c" ] + * a.reverse! #=> ["c", "b", "a"] + * a #=> ["c", "b", "a"] + */ + static VALUE rb_ary_reverse_bang(ary) VALUE ary; @@ -1114,6 +1499,16 @@ rb_ary_reverse_bang(ary) return rb_ary_reverse(ary); } +/* + * call-seq: + * array.reverse -> an_array + * + * Returns a new array containing <i>self</i>'s elements in reverse order. + * + * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"] + * [ 1 ].reverse #=> [1] + */ + static VALUE rb_ary_reverse_m(ary) VALUE ary; @@ -1167,6 +1562,22 @@ sort_unlock(ary) } VALUE +/* + * call-seq: + * array.sort! => array + * array.sort! {| a,b | block } => array + * + * Sorts _self_. Comparisons for + * the sort will be done using the <code><=></code> operator or using + * an optional code block. The block implements a comparison between + * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also + * <code>Enumerable#sort_by</code>. + * + * a = [ "d", "a", "e", "c", "b" ] + * a.sort #=> ["a", "b", "c", "d", "e"] + * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"] + */ + rb_ary_sort_bang(ary) VALUE ary; { @@ -1178,6 +1589,22 @@ rb_ary_sort_bang(ary) return ary; } +/* + * call-seq: + * array.sort => an_array + * array.sort {| a,b | block } => an_array + * + * Returns a new array created by sorting <i>self</i>. Comparisons for + * the sort will be done using the <code><=></code> operator or using + * an optional code block. The block implements a comparison between + * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also + * <code>Enumerable#sort_by</code>. + * + * a = [ "d", "a", "e", "c", "b" ] + * a.sort #=> ["a", "b", "c", "d", "e"] + * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"] + */ + VALUE rb_ary_sort(ary) VALUE ary; @@ -1187,6 +1614,20 @@ rb_ary_sort(ary) return ary; } +/* + * call-seq: + * array.collect {|obj| block } -> an_array + * array.map {|obj| block } -> an_array + * + * Invokes <i>block</i> once for each element of <i>self</i>. Creates a + * new array containing the values returned by the block. + * See also Enumerable#collect</code>. + * + * a = [ "a", "b", "c", "d" ] + * a.collect {|x| x + "!" } #=> ["a!", "b!", "c!", "d!"] + * a #=> ["a", "b", "c", "d"] + */ + static VALUE rb_ary_collect(ary) VALUE ary; @@ -1205,6 +1646,20 @@ rb_ary_collect(ary) return collect; } +/* + * call-seq: + * array.collect! {|obj} ...} => array + * array.map! {|obj} ...} => array + * + * Invokes the block once for each element of _self_self, replacing the + * element with the value returned by _block_. + * See also Enumerable.collect. + * + * a = [ "a", "b", "c", "d" ] + * a.collect! {|x| x + "!" } + * a #=> [ "a!", "b!", "c!", "d!" ] + */ + static VALUE rb_ary_collect_bang(ary) VALUE ary; @@ -1251,6 +1706,21 @@ rb_values_at(obj, olen, argc, argv, func) return result; } +/* + * call-seq: + * array.values_at(selector,... ) => an_array + * Returns an array containing the elements in + * _self_ corresponding to the given selector(s). The selectors + * may be either integer indices or ranges. + * See also </code>.select<code>. + * + * a = %w{ a b c d e f } + * a.values_at(1, 3, 5) + * a.values_at(1, 3, 5, 7) + * a.values_at(-1, -3, -5, -7) + * a.values_at(1..3, 2...5) + */ + static VALUE rb_ary_values_at(argc, argv, ary) int argc; @@ -1260,6 +1730,21 @@ rb_ary_values_at(argc, argv, ary) return rb_values_at(ary, RARRAY(ary)->len, argc, argv, rb_ary_entry); } +/* + * call-seq: + * array.select {|i| block } -> an_array + * + * Invokes the block passing in successive elements from <i>arr</i>, + * returning an array containing those elements for which the block + * returns a true value (equivalent to <code>Enumerable#select</code>). + * + * a = %w{ a b c d e f } + * a.select(1, 3, 5) #=> ["b", "d", "f"] + * a.select(1, 3, 5, 7) #=> ["b", "d", "f", nil] + * a.select(-1, -3, -5, -7) #=> ["f", "d", "b", nil] + * a.select {|v| v =~ /[aeiou]/} #=> ["a", "e"] + */ + static VALUE rb_ary_select(argc, argv, ary) int argc; @@ -1281,6 +1766,23 @@ rb_ary_select(argc, argv, ary) return result; } +/* + * call-seq: + * array.delete(obj) => obj or nil + * array.delete(obj) {| | block } => obj or nil + * + * Deletes items from <i>self</i> that are equal to <i>obj</i>. If + * the item is not found, returns <code>nil</code>. If the optional + * code block is given, returns the result of <i>block</i> if the item + * is not found. + * + * a = [ "a", "b", "b", "b", "c" ] + * a.delete("b") #=> "b" + * a #=> ["a", "c"] + * a.delete("z") #=> nil + * a.delete("z") { "not found" } #=> "not found" + */ + VALUE rb_ary_delete(ary, item) VALUE ary; @@ -1337,6 +1839,20 @@ rb_ary_delete_at(ary, pos) return del; } +/* + * call-seq: + * array.delete_at(index) -> obj or nil + * + * Deletes the element at the specified index, returning that element, + * or <code>nil</code> if the index is out of range. See also + * <code>Array#slice!</code>. + * + * a = %w( ant bat cat dog ) + * a.delete_at(2) #=> "cat" + * a #=> ["ant", "bat", "dog"] + * a.delete_at(99) #=> nil + */ + static VALUE rb_ary_delete_at_m(ary, pos) VALUE ary, pos; @@ -1344,6 +1860,31 @@ rb_ary_delete_at_m(ary, pos) return rb_ary_delete_at(ary, NUM2LONG(pos)); } +/* + * call-seq: + * array.slice!(int) => obj or nil + * array.slice!(start, length) => sub_array or nil + * array.slice!(range) => sub_array or nil + * + * Deletes the element(s) given by an index (optionally with a length) + * or by a range. Returns the deleted object, subarray, or + * <code>nil</code> if the index is out of range. Equivalent to: + * + * def slice!(*args) + * result = self[*args] + * self[*args] = nil + * result + * end + * + * a = [ "a", "b", "c" ] + * a.slice!(1) #=> "b" + * a #=> ["a", "c"] + * a.slice!(-1) #=> "c" + * a #=> ["a"] + * a.slice!(100) #=> nil + * a #=> ["a"] + */ + static VALUE rb_ary_slice_bang(argc, argv, ary) int argc; @@ -1373,6 +1914,16 @@ rb_ary_slice_bang(argc, argv, ary) return rb_ary_delete_at(ary, NUM2LONG(arg1)); } +/* + * call-seq: + * array.reject! {| | block } -> array or nil + * + * Equivalent to <code>Array#delete_if</code>, deleting elements from + * _self_ for which the block evaluates to true, but returns + * <code>nil</code> if no changes were made. Also see + * <code>Enumerable#reject</code>. + */ + static VALUE rb_ary_reject_bang(ary) VALUE ary; @@ -1393,6 +1944,14 @@ rb_ary_reject_bang(ary) return ary; } +/* + * call-seq: + * arr.reject {|item| block } -> an_array + * + * Returns a new array containing the items in _self_ + * for which the block is not true. + */ + static VALUE rb_ary_reject(ary) VALUE ary; @@ -1402,6 +1961,17 @@ rb_ary_reject(ary) return ary; } +/* + * call-seq: + * array.delete_if {|item| block } -> array + * + * Deletes every element of <i>self</i> for which <i>block</i> evaluates + * to <code>true</code>. + * + * a = [ "a", "b", "c" ] + * a.delete_if {|x| x >= "b" } #=> ["a"] + */ + static VALUE rb_ary_delete_if(ary) VALUE ary; @@ -1410,6 +1980,28 @@ rb_ary_delete_if(ary) return ary; } +/* + * call-seq: + * array.zip(arg, ...) -> an_array + * array.zip(arg, ...) {| arr | block } -> nil + * + * Converts any arguments to arrays, then merges elements of + * <i>self</i> with corresponding elements from each argument. This + * generates a sequence of <code>self#size</code> <em>n</em>-element + * arrays, where <em>n</em> is one more that the count of arguments. If + * the size of any arguemnt is less than <code>enumObj#size</code>, + * <code>nil</code> values are supplied. If a block given, it is + * invoked for each output array, otherwise an array of arrays is + * returned. + * + * a = [ 4, 5, 6 ] + * b = [ 7, 8, 9 ] + * + * [1,2,3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]] + * [1,2].zip(a,b) #=> [[1, 4, 7], [2, 5, 8]] + * a.zip([1,2],[8]) #=> [[4,1,8], [5,2,nil], [6,nil,nil]] + */ + static VALUE rb_ary_zip(argc, argv, ary) int argc; @@ -1449,6 +2041,17 @@ rb_ary_zip(argc, argv, ary) return result; } +/* + * call-seq: + * array.transpose -> an_array + * + * Assumes that <i>self</i> is an array of arrays and transposes the + * rows and columns. + * + * a = [[1,2], [3,4], [5,6]] + * a.transpose #=> [[1, 3, 5], [2, 4, 6]] + */ + static VALUE rb_ary_transpose(ary) VALUE ary; @@ -1478,6 +2081,18 @@ rb_ary_transpose(ary) return result; } +/* + * call-seq: + * array.replace(other_array) => array + * + * Replaces the contents of <i>self</i> with the contents of + * <i>other_array</i>, truncating or expanding if necessary. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"] + * a #=> ["x", "y", "z"] + */ + static VALUE rb_ary_replace(copy, orig) VALUE copy, orig; @@ -1496,6 +2111,15 @@ rb_ary_replace(copy, orig) return copy; } +/* + * call-seq: + * array.clear => array + * Removes all elements from _self_. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.clear #=> [ ] + */ + VALUE rb_ary_clear(ary) VALUE ary; @@ -1509,6 +2133,30 @@ rb_ary_clear(ary) return ary; } +/* + * call-seq: + * array.fill(obj) -> array + * array.fill(obj, start [, length]) => array + * array.fill(obj, range ) => array + * array.fill {|i| block } => array + * array.fill(start [, length] ) {|i| block } => array + * array.fill(range) {|i| block } => array + * + * The first three forms set the selected elements of <i>self</i> (which + * may be the entire array) to <i>obj</i>. A <i>start</i> of + * <code>nil</code> is equivalent to zero. A <i>length</i> of + * <code>nil</code> is equivalent to <i>arr</i>.length. The last three + * forms fill the array with the value of the block. The block is + * passed the absolute index of each element to be filled. + * + * a = [ "a", "b", "c", "d" ] + * a.fill("x") #=> ["x", "x", "x", "x"] + * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"] + * a.fill("y", 0..1) #=> ["y", "y", "z", "z"] + * a.fill {|i| i*i} #=> [0, 1, 4, 9] + * a.fill(-2) {|i| i*i*i} #=> [0, 1, 8, 27] + */ + static VALUE rb_ary_fill(argc, argv, ary) int argc; @@ -1580,6 +2228,16 @@ rb_ary_fill(argc, argv, ary) return ary; } +/* + * call-seq: + * array + other_array => an_array + * + * Concatenation---Returns a new array built by concatenating the + * two arrays together to produce a third array. + * + * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ] + */ + VALUE rb_ary_plus(x, y) VALUE x, y; @@ -1596,6 +2254,15 @@ rb_ary_plus(x, y) return z; } +/* + * self.concat(other_array) => array + * + * Appends the elements in other_array to _self_. + * + * [ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ] + */ + + VALUE rb_ary_concat(x, y) VALUE x, y; @@ -1607,6 +2274,21 @@ rb_ary_concat(x, y) return x; } + +/* + * call-seq: + * array * int => an_array + * array * str => a_string + * + * Repetition---With a String argument, equivalent to + * self.join(str). Otherwise, returns a new array + * built by concatenating the _int_ copies of _self_. + * + * + * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ] + * + */ + static VALUE rb_ary_times(ary, times) VALUE ary, times; @@ -1640,6 +2322,26 @@ rb_ary_times(ary, times) return ary2; } +/* + * call-seq: + * array.assoc(obj) => an_array or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first assoc}iated array, + * or +nil+ if no match is found. + * See also Array.rassoc. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + VALUE rb_ary_assoc(ary, key) VALUE ary, key; @@ -1659,6 +2361,20 @@ rb_ary_assoc(ary, key) return Qnil; } +/* + * call-seq: + * array.rassoc(key) -> an_array or nil + * + * Searches through the array whose elements are also arrays. Compares + * <em>key</em> with the second element of each contained array using + * <code>==</code>. Returns the first contained array that matches. See + * also <code>Array#assoc</code>. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + VALUE rb_ary_rassoc(ary, value) VALUE ary, value; @@ -1678,6 +2394,20 @@ rb_ary_rassoc(ary, value) return Qnil; } +/* + * call-seq: + * array == other_array => bool + * + * Equality---Two arrays are equal if they contain the same number + * of elements and if each element is equal to (according to + * Object.==) the corresponding element in the other array. + * + * [ "a", "c" ] == [ "a", "c", 7 ] #=> false + * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true + * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false + * + */ + static VALUE rb_ary_equal(ary1, ary2) VALUE ary1, ary2; @@ -1731,6 +2461,19 @@ rb_ary_hash(ary) return LONG2FIX(h); } +/* + * call-seq: + * array.include?(obj) => true or false + * + * Returns <code>true</code> if the given object is present in + * <i>self</i> (that is, if any object <code>==</code> <i>anObject</i>), + * <code>false</code> otherwise. + * + * a = [ "a", "b", "c" ] + * a.include?("b") #=> true + * a.include?("z") #=> false + */ + VALUE rb_ary_includes(ary, item) VALUE ary; @@ -1746,6 +2489,27 @@ rb_ary_includes(ary, item) return Qfalse; } + +/* + * call-seq: + * array <=> other_array => -1, 0, +1 + * + * Comparison---Returns an integer (-1, 0, + * or +1) if this array is less than, equal to, or greater than + * other_array. Each object in each array is compared + * (using <=>). If any value isn't + * equal, then that inequality is the return value. If all the + * values found are equal, then the return is based on a + * comparison of the array lengths. Thus, two arrays are + * ``equal'' according to Array.<=> if and only if they have + * the same length and the value of each element is equal to the + * value of the corresponding element in the other array. + * + * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1 + * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 + * + */ + VALUE rb_ary_cmp(ary1, ary2) VALUE ary1, ary2; @@ -1787,6 +2551,18 @@ ary_make_hash(ary1, ary2) return hash; } +/* + * call-seq: + * array - other_array => an_array + * + * Array Difference---Returns a new array that is a copy of + * the original array, removing any items that also appear in + * other_array. (If you need set-like behavior, see the + * library class Set.) + * + * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ] + */ + static VALUE rb_ary_diff(ary1, ary2) VALUE ary1, ary2; @@ -1804,6 +2580,17 @@ rb_ary_diff(ary1, ary2) return ary3; } +/* + * call-seq: + * array & other_array + * + * Set Intersection---Returns a new array + * containing elements common to the two arrays, with no duplicates. + * + * [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ] + */ + + static VALUE rb_ary_and(ary1, ary2) VALUE ary1, ary2; @@ -1826,6 +2613,17 @@ rb_ary_and(ary1, ary2) return ary3; } +/* + * call-seq: + * array | other_array => an_array + * + * Set Union---Returns a new array by joining this array with + * other_array, removing duplicates. + * + * [ "a", "b", "c" ] | [ "c", "d", "a" ] + * #=> [ "a", "b", "c", "d" ] + */ + static VALUE rb_ary_or(ary1, ary2) VALUE ary1, ary2; @@ -1853,6 +2651,20 @@ rb_ary_or(ary1, ary2) return ary3; } +/* + * call-seq: + * array.uniq! => array or nil + * + * Removes duplicate elements from _self_. + * Returns <code>nil</code> if no changes are made (that is, no + * duplicates are found). + * + * a = [ "a", "a", "b", "b", "c" ] + * a.uniq! #=> ["a", "b", "c"] + * b = [ "a", "b", "c" ] + * b.uniq! #=> nil + */ + static VALUE rb_ary_uniq_bang(ary) VALUE ary; @@ -1881,6 +2693,16 @@ rb_ary_uniq_bang(ary) return ary; } +/* + * call-seq: + * array.uniq => an_array + * + * Returns a new array by removing duplicate values in <i>self</i>. + * + * a = [ "a", "a", "b", "b", "c" ] + * a.uniq #=> ["a", "b", "c"] + */ + static VALUE rb_ary_uniq(ary) VALUE ary; @@ -1890,6 +2712,16 @@ rb_ary_uniq(ary) return ary; } +/* + * call-seq: + * array.compact! => array or nil + * + * Removes +nil+ elements from array. + * Returns +niL+ if no changes were made. + * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] + * [ "a", "b", "c" ].compact! #=> nil + */ + static VALUE rb_ary_compact_bang(ary) VALUE ary; @@ -1913,6 +2745,16 @@ rb_ary_compact_bang(ary) return ary; } +/* + * call-seq: + * array.compact => an_array + * + * Returns a copy of _self_ with all +nil+ elements removed. + * + * [ "a", nil, "b", nil, "c", nil ].compact + * #=> [ "a", "b", "c" ] + */ + static VALUE rb_ary_compact(ary) VALUE ary; @@ -1922,6 +2764,16 @@ rb_ary_compact(ary) return ary; } +/* + * call-seq: + * array.nitems -> int + * + * Returns the number of non-<code>nil</code> elements in _self_. + * May be zero. + * + * [ 1, nil, 3, nil, 5 ].nitems #=> 3 + */ + static VALUE rb_ary_nitems(ary) VALUE ary; @@ -1967,6 +2819,20 @@ flatten(ary, idx, ary2, memo) return lim - idx - 1; /* returns number of increased items */ } +/* + * call-seq: + * arr.flatten! -> arr or nil + * + * Flattens _self_ in place. + * Returns <code>nil</code> if no modifications were made (i.e., + * <i>arr</i> contains no subarrays.) + * + * a = [ 1, 2, [3, [4, 5] ] ] + * a.flatten! #=> [1, 2, 3, 4, 5] + * a.flatten! #=> nil + * a #=> [1, 2, 3, 4, 5] + */ + static VALUE rb_ary_flatten_bang(ary) VALUE ary; @@ -1992,6 +2858,20 @@ rb_ary_flatten_bang(ary) return ary; } +/* + * call-seq: + * array.flatten -> an_array + * + * Returns a new array that is a one-dimensional flattening of this + * array (recursively). That is, for every element that is an array, + * extract its elements into the new array. + * + * s = [ 1, 2, 3 ] #=> [1, 2, 3] + * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] + * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] + * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + */ + static VALUE rb_ary_flatten(ary) VALUE ary; @@ -2001,6 +2881,14 @@ rb_ary_flatten(ary) return ary; } + +/* Arrays are ordered, integer-indexed collections of any object. + * Array indexing starts at 0, as in C or Java. A negative index is + * assumed to be relative to the end of the array---that is, an index of -1 + * indicates the last element of the array, -2 is the next to last + * element in the array, and so on. + */ + void Init_Array() { |