The Ruby collection Guide (2): Hashes, Sets and Ranges

Recommended for you: Get network issues from WhatsUp Gold. Not end users.
Are iteratively universal attention array and Ruby in the first article. An array is a beautiful and elegant, but for some special cases to better solutions. This article contains some other types of set in Ruby.

The hash table

Sometimes you need a number mapping to another. For example, you may want to map a ID product to a product containing information array. If the product ID is plastic, you can deal with arrays, but this may want to waste more space in ID. The Ruby hash function can be associated with a key value is not necessarily the shaping of the array.


Establish

like in the array, Hash not only has the text initialization syntax, also has a constructor initializer syntax.
1 >> colors = {}
2 >> colors['red'] = 0xff0000
3
4 >> colors = Hash.new
5 >> colors['red'] = 0xff0000


With an array, with the initial value create Hash is feasible. Then you will see the commonly used => (" Hash rocket ").
1 >> colors = {
2 >> 'red' => 0xff0000,
3 >> 'blue' => 0x0000ff
4 >> }
5 => {"red"=>16711680, "blue"=>255}


If you try to not value to a; Hash keys to access, will return to nil (no value). You can pass a parameter to the constructor of this change the defaultvalue.
1 >> h = Hash.new
2 >> h[:blah]
3 => nil
4
5 >> h = Hash.new(0)
6 >> h[:blah]
7 => 0


Note: for a non-existent key access cannot create the key corresponding to thevalue.
1 >> h = {}
2 >> h.size
3 => 0
4 >> h[:blah]
5 >> h.size
6 => 0


Delete

If you want to delete the value hash; the words, you can use the #delete. like in the Lua table, only to set you want to delete the key corresponding to the value nil may be attractive, but the key is still a part of the Hash, therefore also included in the loop iteration.
1 >> colors['red'] = nil
2 >> colors.size
3 => 2
4
5 >> colors.delete('red')
6 >> colors.size
7 => 1


Iteration

Like an array, Hash can also be iterative, just pass it to the processing block is two value instead of avalue.
1 >> hash = {"Juan" => 24, "Isidora" => 35}
2 >> hash.each { |name, age| puts "#{name}: #{age}" }
3 Juan: 24
4 Isidora: 35


Block variables name and age in the example above is just a placeholder. They are optional, but can be any value, but give them meaning is good practice.


With the hash table to rocket (=>) or no hash rocket

Some identified as key value hash table; very popular, because they are described as string but as fast and shaping.
1 >> farm_counts = {
2 >> :cow => 8,
3 >> :chicken => 23,
4 >> :pig => 11,
5 >> }
6 => {:cow=>8, :chicken=>23, :pig=>11}


Starting from Ruby1.9, the hash table identifies the key value can use hash rocket (=>) to scan, this and JavaScript or Python.like.
1 >> farm_counts = {
2 >> cow: 8,
3 >> chicken: 23,
4 >> pig: 11
5 >> }
6 => {:cow=>8, :chicken=>23, :pig=>11}


The two wind are very common, but remember the key value to other types of; can also use the hash rocket to use, so use a semicolon to replace part of the code will make new the big head.


Use the Hash keyword parameter transfer

Python has the ability to use keywords to transfer the keyword parameters of function calls, then in a specific order parameter transfer or transfer specific parameter is not necessary. Although Ruby technology does not provide keyword arguments, but you can use the Hash to simulate this effect. If Hash is the last parameter in a method call, then the curly braces are omitted. 01 >> class Person
02 >> attr_accessor :first, :last, :weight, :height
03
04 >> def initialize(params = {})
05 >> @first = params[:first]
06 >> @last = params[:last]
07 >> @weight = params[:weight]
08 >> @height= params[:height]
09 >> end
10 >> end
11
12 >> p = Person.new(
13 >> height: 170cm,
14 >> weight: 72,
15 >> last: 'Doe',
16 >> first: 'John'
17 >> )


Note: the Params={} strict it is not needed, but there is no parameter transmission, it can protect the code, so as not to throw the parameter error of such errors, but it can also make the argument type the desired more clearly.

The use of an array of domain creating more lightweight Hash

Someone suggested using an array of class to create a more lightweight Hash this very wise idea.

01 $ gem install arrayfields
02
03 >> require 'arrayfields'
04 >> h = ArrayFields.new
05 >> h[:lunes] = "Monday"
06 >> h[:martes] = "Tuesday"
07 >> h.fields
08 => [:lunes, :martes]
09 >> h.values
10 => ["Monday", "Tuesday"]


I am not very familiar with the array domain gem, or is not very familiar with how to use an array of domains in different in implementation of Ruby, but the Ruby tool, to do so is very popular, if you want to serialize the many Hash data, so the array domain may value see see.

Set

If you need a set does not care about the order, but also to ensure that each element is the only, then you may need to set.
Unlike other collection types, you must add the require statement when using the Set class.
1 >> require 'set'


In addition, also different from the array and Hash, Set does not have any special text initialization syntax. However, you can transfer to the new method of the Set array.
1 >> s = Set.new([1,2,3])
2 => #<Set: {1, 2, 3}>


In addition, the to_set method you can use array.
1 >> [1,2,3,3].to_set
2 => #<Set: {1, 2, 3}>


like in the array, Set can also use <<operator, but this time not to use the push method, and to use the add method.
1 >> s = Set.new
2 >> s <<1
3 >> s.add 2


To an element deletion of Set, use the delete method.
1 >> s.delete(1)
2 => #<Set: {2}>


With an array, you can also use the #include? Method to test whether is a member of the Set.
1 >> s.include? 1
2 => false
3 >> s.include? 2
4 => true


Set has a very useful feature is that it can not add already contains elements.
1 >> s = Set.new [1,2]
2 => #<Set: {1, 2}>
3 >> s.add 2
4 => #<Set: {1, 2}>


I have already mentioned the array can perform Boolean operation, very natural, Set can also do this.
1 >> s1 = [1,2,3].to_set
2 >> s2 = [2,3,4].to_set
3
4 >> s1 & s2
5 => #<Set: {2, 3}>
6
7 >> s1 | s2
8 => #<Set: {1, 2, 3, 4}>


With an array of different is, it can also use the ^ operator XOR operation.
1 >> [1,2,3] ^ [2,3,4]
2 => NoMethodError: undefined method `^' for [1, 2, 3]:Array
3
4 >> s1 ^ s2
5 => #<Set: {4, 1}>




Range

In the first part, I have mentioned the Range. The Range class is a kind of quasi collection. It can be set using the Enumerable iterative like the other way, but it can not be arbitrary elements container storage.
1 >> r = Range.new('a', 'c')
2 => 'a'..'c'
3 >> r.each { |i| puts i }
4 a
5 b
6 c


Previously, I show that Range can be used for array slice or generated for the iteration index.
1 >> letters = [:a,:b,:c,:d,:e]
2 >> letters[1..3]
3 => [:b, :c, :d]
4
5 >> (1..3).map { |i| letters[i].upcase }
6 => [:B, :C, :D]


In addition to the array of the slice, Range can simplify the case statement logic.
01 >> def theme(year)
02 >> case year
03 >> when 1970..1979 then "War Bad, Black People Not Bad"
04 >> when 1980..1992 then "Cocaine, Money, and The Future"
05 >> when 1993..2000 then "Gillian Anderson, Sitcoms in The FriendZone, and AOL"
06 >> when 2000..2013 then "RIP, Music"
07 >> end
08 >> end
09
10 >> theme(1987)
11 => "Cocaine, Money, and The Future"


In order to get the answer to how to make full use of Range, stackoverflow can have a look on the automatic generation of random string problem. 1 >> (0...10).map{ ('a'..'z').to_a[rand(26)] }.join
2 => "vphkjxysly"


Summary

This article provides an overview of the Hash, Set and Range. In my next blog entry, I will discuss the Enumberable, Enumberator and the use of such tools good things you can do.
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Crystal at January 29, 2014 - 12:07 PM