updated: 03 April 2013

在编程过程中,最常用到的数据结构就包括 array ,所以掌握到 array 的使用是非常重要的。Array 是一种有序的序列,可以在其中储存各种对象,对,各种的,包括数值,字符串,对象。

Array 创建

Array 的创建是非常容易的,一般最常用的方式都是通过下面的方面来创建一个 Array 的:

>> num = [1, 2, 3, 4]           # => [1, 2, 3, 4]
>> num[0]                       # => 1
>> num[5]                       # => nil   不存在的 index 显示为 nil

可以通过上面的这些方式来创建 array,也可以通过下面的两种来创建新的 array,一种是给变量赋值一个空的数组,另一种方法是使用 Array 类来创建一个新的实例。Array 类是使用 ruby 语言在编程过程中经常需要使用到的类,它包含了很的方法,这些方法可以执行各式各样的任务,在后面就会有详细的介绍。

首先来了解创建两个空 array 的方法:

>> a1 = []                      # => []
>> a2 = Array.new               # => []
>> a1.class                     # => Array
>> a2.class                     # => Array

你还可以通过给 new 方法来指定参数完成创建的过程,第一个参数是数组元素的个数,第二个参数是内容,如果省略第二个参数的话,刚会创建 nil 对象:

>> Array.new(3)                 # => [nil, nil, nil]
>> Array.new(3, 3)              # => [3, 3, 3]
>> Array.new(3) {|num| num + 1} # => [1, 2, 3]

这里也还有一种特殊的方式,是使用 %w 或者 %W 来创建,元素之间无须使用“ , ”号来分隔元素,只需要使用空格就可以了。

>> a3 = %w[this is a new array] # => ["this", "is", "a", "new", "array"]
>> a3.class                     # => Array

同时,还可以通过 to_a() 方法,来将 Range 对象转换成数组元素,当然,还可能将其它的对象也转换也数组对象:

>> (1..9).to_a                  # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> ('a'..'e').to_a              # => ["a", "b", "c", "d", "e"]

Ruby 中的数组元素可以是任何对象,这也是解释性语言中一个非常方便的功能,元素不必为统一的对象,下面是一个例子:

>> mix = [1, "a", true, [1, 2, 3]]
=> [1, "a", true, [1, 2, 3]]
>> mix.class
=> Array

这个叫 mix 的数组中有数字对象,字符串对象,布尔对象和数组对象,非常的易用。

Array 的长度

Array 的长度就是该数组里有多少个元素,可以使用 array 的 length() 和 size() 方法来获得,它们是一样的功能:

>> num = [1, 2, 3, 4]
>> num.length                   # => 4
>> num.size                     # => 4

也可以使用方法来判断数组中有没有元素,empty?() 是常被用到的方法:

>> num.nil?                     # => false
>> num.empty?                   # => false
>> [].nil?                      # => false
>> [].empty?                    # => true

Array 访问

Array 是有序的集合,和所有其它的编程语言一样,从序号 0 开始计数,也就是第一个元素是 0,第二个元素是 1。如果你去访问 array 中不存在的元素的话,ruby 不会返回错误,只会返回一个 nil 对象,这点和其它的编程语言是不一样的。

用上面已经创建好的 num 数组来访问看下效果:

>> num[0]                       # => 1
>> num[5]                       # => nil 访问不存在的元素  

同时还有一些访问方法,可以通过数组长度来访问,也可以通过负数来访问。Array 中的最后一个元素记做 -1,倒数第二个元素记做 -2,看下演示:

>> num[-1]
=> 4
>> num[num.size]                #num.size 是数组的长度,这里为 4
=> nil                          #num 数组的最后一个元素为 num[3],num[4] 就是 nil
>> num[num.size - 1]
=> 4
>> num[-num.size]
=> 1

还可以访问数据内容的范围,同样也是使用 [ ] 方法来操作,第一个参数同样是数组中元素的位置,第二个参数为需要返回的元素个数。

>> num = (1..9).to_a            # 对 num 数组重新进行赋值
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> num[2, 3]
=> [3, 4, 5]
>> num[7, 3]
=> [8, 9]

那如何访问数组中从第几个元素到第几个元素这样的内容,可以使用 Range 来进行操作:

>> num[3..5]                    #从第 4 个元素到第 6 个元素
=> [4, 5, 6]
>> num[3..-1]                   #从第 4 个元素到最后一个元素
=> [4, 5, 6, 7, 8, 9]

还可以使用方法 first() 来获取 array() 中第一个元素和 last() 访问最后一个元素:

>> num.first                    # => 1
>> num.last                     # => 9

Array 元素赋值

对 array 对象中的元素进行赋值和对普通的变量进行赋值是差不多的,只是数组需要指定要操作的是哪一个元素,也可以同时指定对哪几个元素进行操作:

>> num[3] = 5                   #将第 4 个元素改成数字 5
=> 5
>> num
=> [1, 2, 3, 5, 5, 6, 7, 8, 9]
>> num << 10
=> [1, 2, 3, 5, 5, 6, 7, 8, 9, 10]

向数组里面添加其它的元素使用 « 操作符是十分容易的一件事,这也是常常用到的方法。如果在数组后添加一个元素,ruby 自动的会为空白的内容添加上 nil ,下面就是一个例子:

>> num[14] = 15                # => 15
>> num
=> [1, 2, 3, 5, 5, 6, 7, 8, 9, 10, nil, nil, nil, nil, 15]

还有一种比较常用到的方式是使用并行赋值,这是这样的:

>> words = %w[hello world]     # => ["hello", "world"]
>> word1, word2 = words        # => ["hello", "world"]
>> word1                       # => "hello"
>> word2                       # => "world"

这里,一次性的把数组的值赋值给了两个变量,分别为 word1 和 word2,非常方便。

Array 常用 API 及操作

Array 属于 Enumerable 对象的子类,它也因此而继承了该对向的方法,同样的,hash 也是该类的子类,也具备这些方法,它们被统称为集合。

each()

对 array 内的的元素进行迭代是最常用的到的,也就是把 array 中的元素一个接一个的取出来,使用 each() 方法来操作,按序号一次取一个元素:

>> num = (1..9).to_a
>> num.each{|x| print x}        # => 123456789

还有一个不常用的到 each() 方法可以把 index 也就是索引也迭代出来:

>> num.each_with_index{|x,i| print "#{i}:#{x},"}
0:1,1:2,2:3,3:4,4:5,5:6,6:7,7:8,8:9

collect() 和 map()

常用到的方法还有 collect() 方法,它把结果使用到集后中的每一个元素上,但它并不会改变原来集后的内容,它只返回一个新的 array 对象。如果使用带有 ! 的方法,则原数组才会被替换成新的数组对象:

>> num.collect{|x| x * 2 }      # => [2, 4, 6, 8, 10, 12, 14, 16, 18]
>> num                          # => [1, 2, 3, 4, 5, 6, 7, 8, 9]

下面是使用还有 ! 符号的 collect 方法, num 对象被改变了:

>> num.collect!{|x| x * 2 }     # => [2, 4, 6, 8, 10, 12, 14, 16, 18]
>> num                          # => [2, 4, 6, 8, 10, 12, 14, 16, 18]

Ruby 中也有同样的方法,比如 collect 和 map 是同样的功能,length 和 size 也是一样的功能。不信你将 collect() 方法换成 map() 方法试试。

select()

你想找出数组中满足某一条件的内容,就可以使用 select() 方法来完成,它也会返回一个新的数组,同时 ruby 也提供了一个 select!() 方法来将结果返回给自身。

>> num = (1..9).to_a            # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> num.select{|x| x % 2 == 0}   # => [2, 4, 6, 8]
>> num.select{|x| x > 5}        # => [6, 7, 8, 9]

sort()

对一个 array 进行排序,可以按照从小到大的次序,也可以对其进行反向排序:

>> num = [3, 2, 5, 7, 4]
>> num.sort                         # => [2, 3, 4, 5, 7]    正向排序
>> num.sort{|x, y| y <=> x}         # => [7, 5, 4, 3, 2]    反向排序

也可以对字符串进行排序,首先会比较首字母在字母表中的位置,如果相同的话,就会比较第二个字母在字母表的位置,以此类推:

>> word = ["apple", "orange", "banana"]     # => ["apple", "orange", "banana"]
>> word.sort()                              # => ["apple", "banana", "orange"]

include?() 和 index()

通过 include?() 方法可以 array 中查找指定的内容,所以只能返回 找到了 和 没有找到,也就是 ture 和 false,这里省略的 ( ) 来让表达更好理解, ruby 方法中是可以省略括号的:

>> num.include? 4                   # => true
>> num.include? 1                   # => false
>> word.include? "apple"            # => true

使用 member?() 方法也具也同 include?() 方法一样的效果。

而使用 index() 不仅可以知道 array 中有没有指定的对象,而且还可以知道这个对象所处的位置的 index 值是多少,如果有多个值得话,也只会返回找到的第一个:

>> num.index(1)                     # => nil
>> num.index(4)                     # => 4
>> word.index("apple")              # => 0

count() 和 uniq()

使用这两个方法,一个可以计算出 array 中有多少个这种对象,而另一个则是将 array 中相同的对象都只显示一次,这表述还真难,看下演示吧:

>> num = [1, 1, 2, 2, 3, 3, 4, 5, 5]
>> num2.count(2)                        # => 2   出现了 2 次 '2' 这个数字
>> num2.uniq                            # => [1, 2, 3, 4, 5]   

push() pop() 和 shift()

使用这几个方法,可以将数组当成是一个栈来使用,后进先出的栈和先进先出的栈都可以很方便的实现,使用 push() 是向数组的最后压入一个元素,而使用 pop() 将会使数组的最后一个元素被弹出:

>> a = []                           # => []
>> a.push(2)                        # => [2]
>> a.push(3)                        # => [2, 3]
>> a.pop()                          # => 3
>> a                                # => [2]

而 shift() 方法可以使数组的第一个元素被弹出:

>> a.push(4)                        # => [2, 4]
>> a.shift()                        # => 2
>> a                                # => [4]

和字符串相关的方法

Ruby 提供了一些关于 array 操作和字符串相关的方法,可以把 array 对象转换成字符串对象:

>> [1, 2, 3].join                   # => "123"
>> [1, 2, 3].join(',')              # => "1,2,3"
>> [1, 2, 3].to_s                   # => "[1, 2, 3]"
>> [1, 2, 3].inspect                # => "[1, 2, 3]"

这个 inspect() 方法是将数组转换成方例人类阅读的方法,它和 to_s 方法的效果是一样的。

总结

Array 对象是 ruby 中最常用到的数据结构,所以,撑握它的用法是十分的重要,这里居然指出了一般在工作中最常用到的关于 Array 的操作,但还有更多的用法需要我们去查看 API 文档来学习。

参考资料



blog comments powered by Disqus