深入探索

以数组方式操作哈希表

hash_ops.rb

Hash 的 keysvalues 方法都返回一个数组,以便您可以使用各种数组方法来处理它们。以下是一些简单的例子:

  1. h1 = {'key1'=>'val1', 'key2'=>'val2', 'key3'=>'val3', 'key4'=>'val4'}
  2. h2 = {'key1'=>'val1', 'KEY_TWO'=>'val2', 'key3'=>'VALUE_3', 'key4'=>'val4'}
  3. p( h1.keys & h2.keys ) # set intersection (keys)
  4. #=> ["key1", "key3", "key4"]
  5. p( h1.values & h2.values ) # set intersection (values)
  6. #=> ["val1", "val2", "val4"]
  7. p( h1.keys+h2.keys ) # concatenation
  8. #=> [ "key1", "key2", "key3", "key4", "key1", "key3", "key4", "KEY_TWO"]
  9. p( h1.values-h2.values ) # difference
  10. #=> ["val3"]
  11. p( (h1.keys << h2.keys) ) # append
  12. #=> ["key1", "key2", "key3", "key4", ["key1", "key3", "key4", "KEY_TWO"]]
  13. p( (h1.keys << h2.keys).flatten.reverse ) # 'un-nest' arrays and reverse
  14. #=> ["KEY_TWO", "key4", "key3", "key1", "key4", "key3", "key2", "key1"]

附加和连接

请注意两种数组连接是有区别的,使用 + 是将第二个数组的每个元素添加到第一个数组中,使用 << 是将第二个数组作为第一个数组的最后一个元素添加。

append_concat.rb
  1. a =[1,2,3]
  2. b =[4,5,6]
  3. c = a + b #=> c=[1, 2, 3, 4, 5, 6] a=[1, 2, 3]
  4. a << b #=> a=[1, 2, 3, [4, 5, 6]]

另外,<< 会改变第一个数组(接收者,receiver),而 + 会返回一个新的数组,原数组(接收者,receiver)保持不变。

接受者(Receivers),消息(Messages)和方法(Methods)

在面向对象术语中,方法所属的对象被称为接收者 receiver。这表示不像面向过程的语言中那样“调用函数”(calling functions),而是将“消息”(messages)发送给对象。例如,消息 +1 可能会发送给一个整数(integer)对象,而消息 reverse 则可能会发送给一个字符串(string)对象。“接收”消息的对象(receives)试图找到响应消息的方式(即“方法”,method)。例如,字符串(string)对象拥有一个 reverse 方法,所以它可以响应 reverse 消息,而整数(integer)对象没有该方法,也就不能响应。

在使用 << 方法附加数组后,如果你想将每个附加数组的元素都添加到 receiver 数组,而不是将整个附加数组嵌套在 receiver 数组中,你可以使用 flatten 方法:

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

矩阵和向量

Ruby 提供了 Matrix 类,它包含多个行(rows)和列(columns),其每个值都可以表示为向量(vector)(Ruby 也提供 Vector 类)。Matrices 允许您执行矩阵运算。例如,给出两个 Matrix 对象,m1m2,你可以在矩阵中添加每个对应单元格的值,如下所示:

matrix.rb
  1. m3 = m1+m2

Sets

Set 类实现了没有重复值的无序集合(collection)。你可以使用数组来初始化一个 Set,在这种情况下,重复的元素将会被忽略:

例如:

sets.rb
  1. s1 = Set.new( [1,2,3, 4,5,2] )
  2. s2 = Set.new( [1,1,2,3,4,4,5,1] )
  3. s3 = Set.new( [1,2,100] )
  4. weekdays = Set.new( %w( Monday, Tuesday, Wednesday, Thursday,
  5. Friday, Saturday, Sunday ) )

你可以使用 add 方法来添加新的值:

  1. s1.add( 1000 )

merge 方法可以将两个集合(Set)的值组合在一起:

  1. s1.merge(s2)

你可以使用 == 来判断是否相等。包含相同值的两个集合(sets)(记住在创建集合时将删除重复项)被认为是相等的:

  1. p( s1 == s2 ) #=> true