数组类

数组的创建

普通方式

nums = [1, 2, 3, 4, 5]
strs = ["a", "b", "c", "d"]

new

a = Array.new
#=> []

a = Array.new 5
#=> [nil, nil, nil, nil, nil]

a = Array.new 5, 0
#=> [0, 0, 0, 0, 0]

#坑爹问题,注意
a = Array.new(3, [0, 0, 0])
p a
#=>[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

a[0][1] = 2
p a
#=> [[0, 2, 0], [0, 2, 0], [0, 2, 0]]

#解决方案
a = Array.new(3) do
  [0, 0, 0]
end
p a
#=>[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

a[0][1] = 2
p a
#=> [[0, 2, 0], [0, 0, 0], [0, 0, 0]]

%w与%i

#注意,括号内不要加引号
lang = %w(Ruby Python PHP)
p lang
#=> ["Ruby", "Python", "PHP"]

lang = %i(Ruby Python PHP)
p lang
#=> [:Ruby, :Python, :PHP]

#其实任意字符都是可以的,还经常使用|| <> 等
lang = %i|Ruby Python PHP|
p lang
#=> [:Ruby, :Python, :PHP]

to_a

strs = ("a".."d").to_a

color = {black: "#000000", white: "#FFFFFF"}
p color.to_a
#=> [[:black, "#000000"], [:white, "#FFFFFF"]]

split

text = "hello ruby language"
p text.split()
#=> ["hello", "ruby", "language"]

text = "hello|ruby|language"
p text.split("|")
#p text.split(/\|/)
#=> ["hello", "ruby", "language"]

索引用法

a[1]

#倒数第一个
a[-1]

#1~3
a[1..3]

#从2开始,往后2位
a[2, 2]

通过索引创建数组 a.values_at(n1, n2, ...)

alpha = %w(a b c d e f)
p alpha.values_at(1, 3, 5)
#=> ["b", "d", "f"]

作为集合的数组

说明 用法
交集 ary = ary1 & ary2
并集 ary = ary1 | ary2
集合的差 ary = ary1 - ary2
num = [1, 2, 3]
even = [2, 4, 6]

# 两个数组的内容都合并到一个数组里
p num + even
#=> [1, 2, 3, 2, 4, 6]

# 取两个数组的并集
p num | even
#=> [1, 2, 3, 4, 6]

作为列的数组

用push和shift可以实现队列,用push和pop实现栈。

对数组开头的元素的操作 对数组末尾的元素的操作
追加元素 unshift push
删除元素 shift pop
引用元素 first last
ary = ("a".."f").to_a
p ary.first
#=> "a"

p ary.push "e"
#=> ["a", "b", "c", "d", "e", "f", "e"]

ary = ("a".."f").to_a
p ary.shift
#=> "a"
p ary
#=> ["b", "c", "d", "e", "f", "e"]

主要的数组方法

添加元素

a.unshift(item)

将item元素添加到数组的开头

a = [1, 2, 3, 4, 5]
a.unshift(0)
p a
#=> [0, 1, 2, 3, 4, 5]

a << item a.push(item)

在数组a的末尾添加新元素item

a = [1, 2, 3, 4, 5]
a << 6
p a
#=> [1, 2, 3, 4, 5, 6]

a.concat(b) c = a + b

a.concat(b)是具有破坏性的方法, 而c = a + b是创建新的数组

a = [1, 2, 3, 4, 5]
a.concat([8, 9])
p a
#=> [1, 2, 3, 4, 5, 8, 9]

a[n] = item a[n..m] = item a[n, len] = item

替换元素

a = [1, 2, 3, 4, 5, 6, 7, 8]
a[2..4] = 0
#=> [1, 2, 0, 6, 7, 8]

a[1, 3] = 9
#=> [1, 9, 7, 8]

删除元素

a.compact a.compact!

删除数组中的所有nil元素。a.compact!是破坏性方法

a = [1, nil, 3, nil, nil]
a.compact!
p a
#=> [1, 3]

a.delete(x)

删除数组在用x元素

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

a.delete_at(n)

从数组中删除a[n]元素

a = [1, 2, 3, 4, 5]
a. delte_at(2)
p a
#=> [1, 2, 4, 5]

a.delete_if{|item|...} a.reject{|item|...} a.reject!{|item|...}

判断数组a中的个元素item,如果为真,从a中删除item。delete_if和reject!是破坏性方法。

a = [1, 2, 3, 4, 5]
a.delete_if{|i| i > 3}
p a 
#=> [1, 2 ,3]

a.slice!(n) a.slice!(n..m) a.slice!(n, len)

删除数组a中指定的部分,并返回删除部分的值。

a = [1, 2, 3, 4, 5]
p a.slice!(1, 2)
#=> [2, 3]

p a
#=> [1, 4, 5]

a.uniq a.uniq!

删除数组a中重复的元素。

a = [1, 2, 3, 4, 3, 2, 1]
a.uniq!
p a
#=> [1, 2, 3, 4]

a.shift

删除数组a开头的元素,并返回删除的值。

a = [1, 2, 3, 4, 5]
a.shift
#=> 1

p a
#=> [2, 3, 4, 5]

a.pop

删除数组a末尾的元素,并返回删除的值

a = [1, 2, 3, 4, 5]
a.pop
#=> 5

p a
#=> [1, 2, 3, 4]

替换元素

a.collect{|item|...} a.collect!{|item|...} a.map{|item|...} a.map!{|item|...}

用块处理,得到新数组

a = [1, 2, 3, 4, 5]
a.collect!{|item| item * 2}
p a

#=> [2, 4, 6, 8, 10]

a.fill(value) a.fill(value, begin) a.fill(value, begin, len) a.fill(value, n..m)

将数组a的元素替换为value

p [1, 2, 3, 4, 5].fill(0)
#=> [0, 0, 0, 0, 0]

p [1, 2, 3, 4, 5].fill(0, 2)
#=> [1, 2, 0, 0, 0]

p [1, 2, 3, 4, 5].fill(0, 2, 2)
#=> [1, 2, 0, 0, 5]

p [1, 2, 3, 4, 5].fill(0, 2..3)
#=> [1, 2, 0, 0, 5]

a.flatten a.flatten!

平坦化数组a。展开嵌套数组,使之变为一个大数组。

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

a.reverse a.reverse!

反转数组a的元素顺序

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

a.sort a.sort! a.sort{|i, j|...} a.sort!{|i, j|...}

对数组进行排序,排序方法可以由块指定。没有块,使用 <=>比较

a = [2, 4, 3 ,5 ,1]
a.sort!
p a
#=> [1, 2, 3, 4, 5]

a.sort_by{|i|...}

根据块的运行结果对数组进行排序

a = [2, 4, 3 ,5 ,1]
p a.sort_by{|i| -i}
#=> [5, 4, 3, 2, 1]

同时访问多个数组

第一种

ary1 = [1, 2, 3, 4, 5]
ary2 = [10, 20, 30, 40, 50]
ary3 = [100, 200, 300, 400, 500]

i  = 0
result = []
while i < ary1.length
  result << ary1[i] + ary2[i] + ary3[i]
  i += 1
end
p result

第二种

ary1 = [1, 2, 3, 4, 5]
ary2 = [10, 20, 30, 40, 50]
ary3 = [100, 200, 300, 400, 500]

i  = 0
result = []
ary1.each_with_index do |item, index|
  result << item + ary2[index] + ary3[index]
end
p result

第三种

ary1 = [1, 2, 3, 4, 5]
ary2 = [10, 20, 30, 40, 50]
ary3 = [100, 200, 300, 400, 500]

i  = 0
result = []
ary1.zip(ary2, ary3) do |a, b ,c|
  result << a + b + c
end
p result

循环

ary = [1, 2, 3, 4, 5]

for i in ary
    p i
end

ary.each do |i|
    p i
end

ary.each_with_index |elem, i|
    p "第#{i+1}个元素是#{elem}\n。"
end

#这种方法循环完,ary也就不存在了
while item = ary.pop
    p item
end

自定义模块,实现PHP的foreach

module ArrayModule
  def foreach
    key = 0
    self.each do |value|
      yield(key, value)

      key += 1
    end
  end
end

class Array
  #将自己定义的模块Mix-in进Array类
  include ArrayModule
end

#p Array.include? ArrayModule

a = [1, 2, 3, 4, 5]
a.foreach do |key, value|
  p [key, value]
end

自定义迭代器,实现foreach

def foreach(ary, &block)
  key = 0
  ary.each do |value|
    block.call key, value
    key += 1
  end
end

ary = [1, 2, 3]

#块中的代码,将作为Proc对象传到&block
foreach ary do |key, value|
  p [key, value]
end