Array

数组类。数组的元素可以是任意的Ruby对象。通常使用数组表达式

[1, 2, 3]

来生成数组。

超类:

包含的模块:

类方法:

Array[item,...]

生成一个以参数为数组元素的数组。

Array.new([size[, val]])
Array.new(ary) ((<ruby 1.7 特性>))
Array.new(size) {|index| ... } ((<ruby 1.7 特性>))

生成数组。若指定了size的话,就生成一个相应大小的数组,并以nil进行初始化。若指定了val的话,则把该对象设定给每个数组元素。(这并不意味着将nil复制给每个元素。此时,所有元素都会调用同一个对象val trap::Array)。

ruby 1.7 特性:若使用第二种形式的话,则将拷贝参数所指的数组并将其返回。

p Array.new([1,2,3]) # => [1,2,3]

在第三种形式中,将使用块的计算结果来设定值。在设定每个数组元素时都会即计算该块,因此可以将所有元素都变成某对象的拷贝。

p Array.new(5) {|i| i }         # => [0, 1, 2, 3, 4]

ary = Array.new(3, "foo")
ary.each {|obj| p obj.id }
# => 537774036
     537774036
     537774036

ary = Array.new(3) { "foo" }
ary.each {|obj| p obj.id }
# => 537770448
     537770436
     537770424

方法:

self[nth]

返回第nth个数组元素。首元素算做第0个元素。若nth值为负,则看作是从尾部算起的索引值(尾元素算做第-1个元素)。若第nth个元素不存在,则返回nil。

self[start..end]

以数组形式返回从第start个元素到第end个元素间的所有元素。若start值为负,则看作是从尾部算起的索引值(尾元素算做第-1个元素)。若start的值超出数组范围则返回nil。若end的值超出数组长度时,超出的部分将被忽略。另外,若范围的起点比终点还大时,返回nil。

self[start, length]

以数组形式返回从第start个元素算起的length个数组元素。若start值为负,则看作是从尾部算起的索引值(尾元素算做第-1个元素)。若length超出从第start个元素算起的剩余长度时,超过部分将被忽略。若length为负,则返回nil。

self[nth]=val

将第nth个数组元素的值设定为val。若nth超出数组范围时,将自动加长数组并以nil对新增部分进行初始化。

返回val

self[start..end]=val

将从第start个数组元素到第end个数组元素间的所有元素替换为val的内容。若val并非数组时,则就以val进行替换。若val的元素个数过多时,后面的元素将会发生移位。

valnil或空数组[]时,将删除从startend的元素。

例:

ary = [0, 1, 2, 3, 4, 5]
ary[0..2] = ["a", "b"]
p ary

# => ["a", "b", 3, 4, 5]

ary[2..4] = nil
p ary

# => ["a", "b"]

返回val

self[start, length]=val

将从索引start算起的length个数组元素替换为val的内容。若val不是数组时,则调用val.to_ary或使用[val]进行替换。返回val

例:

ary = [0, 1, 2, 3]
ary[1, 2] = ['a', 'b', 'c']
p ary                        # => [0, "a", "b", "c", 3]
ary[2, 1] = 99
p ary                        # => [0, "a", 99, "c", 3]
ary[1, 0] = ['inserted']
p ary                        # => [0, "inserted", "a", 99, "c", 3]
self + other

selfother的内容连起来后生成新数组并返回该数组。若other并非数组时则使用other.to_ary的返回值。若该返回值依然不是数组时,则引发TypeError异常。

例:

a = [1, 2]
b = [8, 9]
p a + b     #=> [1, 2, 8, 9]
p a         #=> [1, 2]        (没有变化)
p b         #=> [8, 9]        (也没有变化)
self * times

将数组内容重复多次后生成一个新数组并返回该数组。请注意,数组元素的值并没有被拷贝 trap::Array

例:

p [1, 2, 3] * 3  #=> [1, 2, 3, 1, 2, 3, 1, 2, 3]

times为字符串,则其动作等同于self.join(times)

p [1,2,3] * ","
# => "1,2,3"
self - other

集合的补集运算。从self中删除other的元素后生成一个新数组并返回该数组。重复元素将被清除。

other并非数组的话,将尝试隐式地调用to_ary方法进行变换。

ruby 1.8 特性: 重复元素将被保留。

p([1, 2, 1, 3, 1, 4, 1, 5] - [2, 3, 4, 5])
# => [1, 1, 1, 1]

p([1, 2, 1, 3, 1, 4, 1, 5] - [1, 2, 3, 4, 5])
# => []
self & other

集合的交集运算。将同属于两个数组的元素重组为一个新数组并返回该数组。重复元素将被清除。若other并非数组的话,将尝试隐式地调用to_ary方法进行变换。

Object#eql?判断元素是否重复。

self | other

集合的并集运算。将任属两数组之一的元素重组为一个新数组并返回该数组。重复元素将被清除。若other并非数组的话,将尝试隐式地调用to_ary方法进行变换。

Object#eql?判断元素是否重复。

self << obj

obj追加到数组尾部。效果等同于Array#push

ary = [1]
ary << 2
p ary      # [1, 2]

因该方法返回值为self,所以可以连写,如下所示。

ary = [1]
ary << 2 << 3 << 4
p ary   #=> [1, 2, 3, 4]
self <=> other

使用<=>来依次比较selfother中的各个元素。若self大则返回正整数;若相等返回0;若小则返回负整数。如果各个元素均相等,且其中一个数组已到达尾部时,则认定较短的数组为小。

self == other

使用==来依次比较selfother中的各个元素,若所有元素均相等时返回真。

assoc(key)

对数组中的元素数组进行检索,若某元素数组的首元素与key相等时就返回该元素数组。使用==操作符进行比较。若没有符合条件的元素数组就返回nil。

例:

ary = [[1,15], [2,25], [3,35]]
p ary.assoc(2)           # => [2, 25]
p ary.assoc(100)         # => nil
p ary.assoc(15)          # => nil

另外,请参考Array#rassoc

at(pos)

返回位于pos的数组元素。与self[pos]相同。

clear

删除数组中的所有元素。返回self

例:

ary = [1, 2]
ary.clear
p ary     #=> []
clone
dup

生成一个与receiver内容一样的新数组并返回它。clone会拷贝frozen tainted singleton-class等信息,而dup则只拷贝内容。

然而,无论是哪个方法都不会拷贝数组元素本身。也就是进行“浅层(shallow)”拷贝。

例:

ary = ['string']
p ary             #=> ["string"]
copy = ary.dup
p copy            #=> ["string"]

ary[0][0...3] = ''
p ary             #=> ["ing"]
p copy            #=> ["ing"]
collect! {|item| ..}
map! {|item| ..}

依次将数组的各个元素传给块进行计算,然后以计算结果来替换该数组元素。请参考Enumerable#collect

返回self

例:

ary = [1, 2, 3]
ary.map! {|i| i * 3 }
p ary   #=> [3, 6, 9]
compact
compact!

compactself中删除值为nil的元素后生成新数组并返回它。compact!是具有破坏性的,若对原数组进行了改动就返回self,若没有进行改动则返回nil。

例:

ary = [1, nil, 2, nil, 3, nil]
p ary.compact   #=> [1, 2, 3]
p ary           #=> [1, nil, 2, nil, 3, nil]
ary.compact!
p ary           #=> [1, 2, 3]
p ary.compact!  #=> nil
concat(other)

other连接到self末尾(该动作具有破坏性)。返回self

例:

array = [1, 2]
a     = [3, 4]
array.concat a
p array          # => [1, 2, 3, 4]
p a              # => [3, 4]       # 没有变化
delete(val)
delete(val) { ... }

使用==来分别比较val与每个数组元素,若相等则删除该元素。若发现了与val相等的元素就返回val

若没有发现与val相等的元素则返回nil,若指定了块的话就对块进行计算并返回结果。

例:

array = [1, 2, 3, 2, 1]
p array.delete(2)       #=> 2
p array                 #=> [1, 3, 1]

# 若向无块的参数传递了 nil 时,则无法从其返回值中判断
# 到底有没有进行删除
ary = [nil,nil,nil]
p ary.delete(nil)       #=> nil
p ary                   #=> []
p ary.delete(nil)       #=> nil
delete_at(pos)

删除pos所指位置的元素并返回它。若pos超出数组范围则返回nil

at一样,可以使用负的索引从尾部起指定元素。

例:

array = [0, 1, 2, 3, 4]
array.delete_at 2
p array             #=> [0, 1, 3, 4]
delete_if {|x| ... }
reject! {|x| ... }

依次将元素传给块进行计算,若结果为真就删除相应元素。

delete_if通常返回self。若没有删除任何元素时,reject!会返回nil

each {|item| .... }

依次使用每个元素来计算块。返回self

例:

# 依次显示1、2、3
[1, 2, 3].each do |i|
  puts i
end

不能使用each(或标准的方法)来取出多个值进行循环。目前,必需定义下列方法才能达到目的。

例:

class Array
  def every(&block)
    arity = block.arity
    return self.each(&block) if arity <= 0

    i = 0
    while i < self.size
      yield(*self[i, arity])
      i += arity
    end
    self
  end
end

ary = [1,2,3]
ary.every {|i| p i}
# => 1
#    2
#    3
ary.every {|i,j| p [i,j]}
# => [1, 2]
#    [3, nil]
ary.every {|i,j,k| p [i,j,k]}
# => [1, 2, 3]
ary.every {|*i| p *i}
# => 1
#    2
#    3
each_index {|index| .... }

依次使用每个元素的索引来对块进行计算。同下

(0 ... ary.size).each {|index| ....  }

返回self

empty?

若数组元素数目为0则返回真。

eql?(other)

使用Object#eql?来依次计算selfother的各个元素,若所有元素均相等则返回真。

fetch(nth) ((<ruby 1.7 特性>))
fetch(nth, ifnone) ((<ruby 1.7 特性>))
fetch(nth) {|nth| ... } ((<ruby 1.7 特性>))

Array#[nth]一样,返回第nth个元素。但若没有第nth个元素的话,它的运作就有别于Array#[nth]了。

第一种形式会引发IndexError异常。第二种形式会返回参数ifnone。而第三种形式会返回块的计算结果。

Array#[nth]与Array#fetch(nth, nil)相同。

fill(val)
fill(val, start[, length])
fill(val, start..end)
fill {|index| ... } ((<ruby 1.7 特性>))
fill(start[, length]) {|index| ... } ((<ruby 1.7 特性>))
fill(start..end) {|index| ... } ((<ruby 1.7 特性>))

val赋值给数组中被指定的范围内的所有元素。在第二种形式中,若省略length则意味着将指定范围扩大到数组尾部。若指定范围最终超出原数组的长度时,将自动加长原数组,并以val来对新增元素进行初始化。

该方法并不是使用val的拷贝,而是用val本身进行赋值(trap::Array)。

ruby 1.7 特性:

若没有指定val,而是代之以块时,则以块的计算值进行赋值。对每个元素进行赋值时都会重新计算块,所以被赋值的元素都是某对象的拷贝。传给块的形参的值,是从start开始的索引。

ary = []
p ary.fill(1..2) {|i| i}        # => [nil, 1, 2]
p ary.fill(0,3) {|i| i}         # => [0, 1, 2]
p ary.fill { "foo" }            # => ["foo", "foo", "foo"]
p ary.collect {|v| v.id }       # => [537770124, 537770112, 537770100]

ruby 1.8 特性:在1.8.0版本中有bug,块的形参会出问题。

ary = []
p ary.fill(1..2) {|i| i}        # => [2, 4, 6]  <- bug
p ary.fill(0,3) {|i| i}         # => [1, 3, 5]  <- bug
p ary.fill { "foo" }            # => ["foo", "foo", "foo"]
p ary.collect {|v| v.id }       # => [537770124, 537770112, 537770100]
first
first(n) ((<ruby 1.8 特性>))

返回数组的首元素。若没有首元素则返回nil

例:

p [0, 1, 2].first   #=> 0
p [].first          #=> nil

ruby 1.8 特性:若指定了可选参数n时,将以数组形式返回前n个元素。n必须大于0。

ary =  [0, 1, 2]
p ary.first(0)
p ary.first(1)
p ary.first(2)
p ary.first(3)
p ary.first(4)
# => []
     [0]
     [0, 1]
     [0, 1, 2]
     [0, 1, 2]

请参考Array#last

flatten
flatten!

将带嵌套的数组重整为不带嵌套的单纯数组,并返回它。flatten!的重整具有破环性,若原数组不带嵌套则返回nil

例:

p [1, [2, 3, [4], 5]].flatten   #=> [1, 2, 3, 4, 5]

array = [[[1, [2, 3]]]]
array.flatten!
p array                         #=> [1, 2, 3]
include?(val)

若数组中包含==val的元素就返回真。

index(val)

返回数组中第一个==val的元素的位置。若没有与其相等的元素则返回nil

indexes(index_1, ... , index_n) ((<obsolete>))
indices(index_1, ... , index_n) ((<obsolete>))

以数组形式返回其索引值与各参数值相等的元素。若指定了超出范围的索引值时,将指派nil与其对应。

例:

ary = %w( a b c d e )
p ary.indexes( 0, 2, 4 )          #=> ["a", "c", "e"]
p ary.indexes( 3, 4, 5, 6, 35 )   #=> ["d", "e", nil, nil]
p ary.indexes( 0, -1, -2 )        #=> ["a", "e", "d"]
p ary.indexes( -4, -5, -6, -35 )  #=> ["b", "a", nil, nil]

ruby 1.8 特性:在1.8版本中,该方法已被禁用。使用时会出现警告。您可以使用Array#values_at来取代它。

insert(nth, val[, val2 ...])
insert(nth, [val[, val2 ...]]) ((<ruby 1.8 特性>))

ruby 1.7 特性

在索引为nth的元素前面插入第2参数以后的值。返回self。其定义如下。

class Array
  def insert( n, *vals )
    self[n, 0] = vals
    self
  end
end

例:

ary = %w( foo bar baz )
ary.insert 2, 'a', 'b'
p ary                  # => ["foo", "bar", "a", "b", "baz"]

ruby 1.8 特性:若没有指定任何val时,将不作任何动作。

join([sep])

sep字符串夹在各元素中间使数组转换为字符串,并返回该字符串。

若数组元素并非字符串的话,就调用to_s然后再进行连接。若元素依然是数组时,将再归调用(同样适用sep)join来连接字符串。

sepnil则使用空字符串。

若参数sep被省略,则使用变量$,的值。$,的默认值为nil。

注:若元素中包含数组本身造成无限嵌套时,将作如下处理。

ary = [1,2,3]
ary.push ary
p ary           # => [1, 2, 3, [...]]
p ary.join      # => "123123[...]"
last
last(n) ((<ruby 1.8 特性>))

返回数组末尾的元素。若数组为空时,返回nil。

p [0, 1, 2].last   #=> 2
p [].last          #=> nil

ruby 1.8 特性:若指定了可选参数n时,将返回末尾的n个元素。n必须大于0。

ary =  [0, 1, 2]
p ary.last(0)
p ary.last(1)
p ary.last(2)
p ary.last(3)
p ary.last(4)
# => []
     [2]
     [1, 2]
     [0, 1, 2]
     [0, 1, 2]

请参考Array#first

length
size

返回数组长度。若数组为空则返回0。

nitems

返回非nil元素的个数。

pack(template)

按照template所指字符串的样式,以二进制的形式将数组的内容打包成字符串,并返回该字符串。模板(template)中包含规定形式的字符串和长度(省略时为1)。若指定的地方出现了*表示“所有剩余数据”的长度。关于规定形式的字符串,请参考pack模板字符串

pop

删除末尾元素并返回它。若数组为空则返回nil。

请参考push, shift, unshift

例:

array = [1, [2, 3], 4]
p array.pop      # => 4
p array.pop      # => [2, 3]
p array          # => [1]

p array.pop      # => 1
p array.pop      # => nil
p array          # => []
push(obj1[, obj2 ...])
push([obj1[, obj2 ...]]) ((<ruby 1.8 特性>))

依次将obj1, obj2 ...添加到数组结尾。

请参考pop, shift, unshift

返回self

例:

array = [1, 2, 3]
array.push 4
array.push [5, 6]
array.push 7, 8
p array          # => [1, 2, 3, 4, [5, 6], 7, 8]

ruby 1.8 特性:若未指定参数则不作任何动作。

rassoc(obj)

假定self是数组中的元素数组,若首次发现元素数组中索引为1的元素与obj相等时就返回该元素。使用==操作符进行比较。

若没有符合条件的元素数组则返回nil

例:

a = [[15,1], [25,2], [35,3]]
p a.rassoc(2)    # => [25, 2]

请参考Array#assoc

replace(another)

以数组another来替换该数组的内容。返回self

例:

a = [1, 2, 3]
a.replace [4, 5, 6]
p a                 #=> [4, 5, 6]
reverse
reverse!

reverse将所有元素以逆序重新排列生成新数组并返回它。reverse!的逆序排列过程具有破环性。

reverse通常返回新数组。若数组只有1个元素,reverse!会返回nil,除此以外将返回self。

ruby 1.8 特性:通常返回self。

reverse_each {|item| ... }

对各个元素以逆序对块进行计算。返回self。

rindex(val)

返回最后一个== val的元素的索引值。若没有符合条件的元素时返回nil

例:

p [1, 0, 0, 1, 0].rindex(1)   #=> 3
p [1, 0, 0, 0, 0].rindex(1)   #=> 0
p [0, 0, 0, 0, 0].rindex(1)   #=> nil
shift

删除数组的首元素并返回它。剩余元素依次提前。若数组为空返回nil。

请参考push, pop, unshift

slice(pos[, len])
slice(start..last)

self[]相同。

slice!(pos[, len])
slice!(start..last)

删除指定的元素并返回它。若没有可删除的元素时返回nil。

sort
sort!
sort {|a, b| ... }
sort! {|a, b| ... }

对数组内容进行排序。若带块调用时,将把2个参数传给块,然后使用块的计算结果进行比较。若没有块时,使用<=>操作符进行比较。sort将生成一个经过排序的新数组并返回它。sort!的对self的排序过程具有破环性。

ruby 1.7 特性:在1.6以前的版本中,当数组元素的个数少于2个时,sort!会返回nil。而在1.7版本中通常返回self。

to_a
to_ary

原封不动地返回self

to_s

与self.join($,)相同。

transpose

ruby 1.7 特性

self看作是由行和列构成的矩阵,然后进行行列互调(将行和列互换)。生成一个新数组并返回它。若原数组为空,则生成空数组并返回它。若原数组为一维数组会引发TypeError异常。若各个元素中包含的子元素个数不一时,会引发IndexError异常。

p [[1,2],
   [3,4],
   [5,6]].transpose
# => [[1, 3, 5], [2, 4, 6]]

p [].transpose
# => []

p [1,2,3].transpose

# => -:1:in `transpose': cannot convert Fixnum into Array (TypeError)
        from -:1

p [[1,2],
   [3,4,5],
   [6,7]].transpose
# => -:3:in `transpose': element size differ (3 should be 2) (IndexError)
uniq
uniq!

uniq会删除数组中的重复元素后生成新数组并返回它。剩下的元素会向前移动。uniq!具有破环性,若进行了删除则返回self,若没有删除则返回nil。

使用Object#eql?来判定元素是否重复。

例:

p [1, 1, 1].uniq         #=> [1]
p [1, 4, 1].uniq         #=> [1, 4]
p [1, 3, 2, 2, 3].uniq   #=> [1, 3, 2]
unshift(obj1[, obj2 ...])
unshift([obj1[, obj2 ...]]) ((<ruby 1.8 特性>))

依次将obj1, obj2 ...插到数组的头部。返回self

请参考push, pop, shift

例:

arr = [1,2,3]
arr.unshift 0
p arr             #=> [0, 1, 2, 3]
arr.unshift [0]
p arr             #=> [[0], 0, 1, 2, 3]
arr.unshift 1, 2
p arr             #=> [1, 2, [0], 0, 1, 2, 3]

ruby 1.8 特性:若未指定参数则不作任何动作。

values_at(index_1, ... , index_n)

ruby 1.8 特性

以数组形式返回其索引值与各参数值相等的元素。若指定了超出范围的索引值时,将指派nil与其对应。(与indexes, indices相同)

例:

ary = %w( a b c d e )
p ary.values_at( 0, 2, 4 )          #=> ["a", "c", "e"]
p ary.values_at( 3, 4, 5, 6, 35 )   #=> ["d", "e", nil, nil, nil]
p ary.values_at( 0, -1, -2 )        #=> ["a", "e", "d"]
p ary.values_at( -4, -5, -6, -35 )  #=> ["b", "a", nil, nil]