ruby arrays
在编程过程中,最常用到的数据结构就包括 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