Ruby Data Structures: Difference between revisions
Jump to navigation
Jump to search
(23 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
2e-20 # Float | 2e-20 # Float | ||
?a # character code for 'a', which is 97 | ?a # character code for 'a', which is 97 | ||
1_048_576 # same as 1048576 | |||
Float::MIN # 2.2250738585072e-308 (on this machine) | |||
Float::MAX # 1.79769313486232e+308 | |||
Float::EPSILON # 2.22044604925031e-16 | |||
</source> | |||
=== Operations === | |||
<source lang="ruby"> | |||
8.to_f # 8.0 | |||
64**2 # 4096 | |||
b = 64**0.5 # 8.0 | |||
</source> | |||
=== Random Numbers === | |||
<source lang="ruby"> | |||
a = rand # Float in [0, 1) | |||
a = rand(10) # Fixnum in 0 <= a < 10 | |||
</source> | |||
=== Math === | |||
<source lang="ruby"> | |||
Math.sqrt(4) # 2.0 | |||
</source> | |||
=== Parsing Strings to get Numbers === | |||
<source lang="ruby"> | |||
"123".to_i # 123 | |||
Integer("123") # 123 | |||
"junk".to_i # silently returns 0 | |||
Integer("junk") # error | |||
"123junk".to_i # 123 | |||
Integer("123junk") # error | |||
" 123 ".to_i # 123 | |||
Integer(" 123 ") # 123 | |||
"3.1416".to_f # 3.1416 | |||
Float("2.718") # 2.718 | |||
"2.9979246e5".to_f # 299792.46 | |||
Float("6.02e23") # 6.02e23 | |||
</source> | |||
=== Formatting Numbers === | |||
<source lang="ruby"> | |||
x = 345.6789 | |||
printf("x = %6.2f\n", x) # x = 345.68, prints immediately | |||
sprintf("x = %6.2f\n", x) # returns a String | |||
"x = %6.2f\n" % x # same thing | |||
</source> | </source> | ||
Line 26: | Line 72: | ||
letter | letter | ||
</source> | </source> | ||
NOTE: if you want to indent the closing "letter", use <code><<-letter</code> to start the here document | |||
=== Concatenation === | === Concatenation === | ||
Line 38: | Line 85: | ||
"The value is #{ some expression }." # substitute the value of an arbitrary expression | "The value is #{ some expression }." # substitute the value of an arbitrary expression | ||
"My name is #{$name}." # substitute the value of a variable | "My name is #{$name}." # substitute the value of a variable | ||
"My name is #$name." # shortcut for | "My name is #$name." # shortcut; only works for global, class, instance variables | ||
str = proc {|x,y,z| "The numbers are #{x}, #{y}, and #{z}" } | |||
s1 = str.call(3,4,5) # The numbers are 3, 4, and 5 | |||
# formatted output | |||
name = "Bob" | name = "Bob" | ||
age = 28 | age = 28 | ||
Line 44: | Line 95: | ||
str = sprintf("%-20s %3d", name, age) | str = sprintf("%-20s %3d", name, age) | ||
str = "%-20s %3d" % [name, age] # Same as previous example | str = "%-20s %3d" % [name, age] # Same as previous example | ||
# sub and gsub | |||
"abababa".sub("a", "A") # "Abababa" | "abababa".sub("a", "A") # "Abababa" | ||
"abababa".gsub("a", "A") # "AbAbAbA" | "abababa".gsub("a", "A") # "AbAbAbA" | ||
Line 65: | Line 118: | ||
x.include? "bc" # true | x.include? "bc" # true | ||
x["cde"] = "CDE" # x is now "abCDEfg" | x["cde"] = "CDE" # x is now "abCDEfg" | ||
x.count("ae") # 2, the number of matching characters | |||
</source> | </source> | ||
Line 85: | Line 139: | ||
x.empty? # false | x.empty? # false | ||
x.upcase # "ABCDEFG" | x.upcase # "ABCDEFG" | ||
x.upcase.downcase # "abcdefg" | |||
x.reverse # "gfedcba" | |||
x.delete("ae") # "bcdfg" | |||
"abc\r\n".chomp # "abc", remove trailing newline chars | "abc\r\n".chomp # "abc", remove trailing newline chars | ||
" \tabc\n".strip # "abc", trim whitespace | " \tabc\n".strip # "abc", trim whitespace | ||
ruler = "+" + ("."*4+"5"+"."*4+"+")*3 # "+....5....+....5....+....5....+" | ruler = "+" + ("."*4+"5"+"."*4+"+")*3 # "+....5....+....5....+....5....+" | ||
</source> | |||
=== MD5 hash === | |||
<source lang="ruby"> | |||
require 'md5' # already included in Rails | |||
secret = Digest::MD5.hexdigest(password) | |||
</source> | |||
=== Encoding and Decoding base64 Strings === | |||
<source lang="ruby"> | |||
x = "abcdefg" | |||
[x].pack("m") # "YWJjZGVmZw==\n" | |||
[x].pack("m").unpack("m") # ["abcdefg"] | |||
</source> | </source> | ||
Line 100: | Line 170: | ||
<source lang="ruby"> | <source lang="ruby"> | ||
[1, 2, 3] << 4 # [1, 2, 3, 4] | [1, 2, 3] << 4 # [1, 2, 3, 4] | ||
[1, 2] |= [3, 4] # [1, 2, 3, 4] | |||
</source> | </source> | ||
Line 111: | Line 182: | ||
<source lang="ruby"> | <source lang="ruby"> | ||
my_array.each do |e| { do something with e } | my_array.each do |e| { do something with e } | ||
</source> | |||
or | |||
<source lang="ruby"> | |||
for e in my_array | |||
do something with e | |||
end | |||
</source> | </source> | ||
Line 123: | Line 200: | ||
x[0,2] # ["a", "b"] | x[0,2] # ["a", "b"] | ||
x[0..2] # ["a", "b", "c"] | x[0..2] # ["a", "b", "c"] | ||
x[1..-1] # ["b", "c"] | |||
x.index("a") # 0 | x.index("a") # 0 | ||
x.include? "a" # true | x.include? "a" # true | ||
Line 208: | Line 286: | ||
<source lang="ruby"> | <source lang="ruby"> | ||
my_time = Time.local(2007, 9, 11, 17, 30, 13) # Tue Sep 11 17:30:13 -0700 2007 | my_time = Time.local(2007, 9, 11, 17, 30, 13) # Tue Sep 11 17:30:13 -0700 2007 | ||
another_date = '2011-09-21'.to_date | |||
yet_another = DateTime.strptime('2015-04-27 4:45 PM', '%Y-%m-%d %H:%M %p') | |||
</source> | </source> | ||
Line 220: | Line 300: | ||
<source lang="ruby"> | <source lang="ruby"> | ||
require 'date' | require 'date' | ||
xmas = Date.parse('12/25/2010') # works for usual formats | |||
today = Date.today | today = Date.today | ||
today.to_s # "2007-09-12" | today.to_s # "2007-09-12" |
Latest revision as of 23:57, 27 April 2015
Numbers
123 # integer of type Fixnum
12345678901234567890 # Bignum: an integer of arbitrary length
2e-20 # Float
?a # character code for 'a', which is 97
1_048_576 # same as 1048576
Float::MIN # 2.2250738585072e-308 (on this machine)
Float::MAX # 1.79769313486232e+308
Float::EPSILON # 2.22044604925031e-16
Operations
8.to_f # 8.0
64**2 # 4096
b = 64**0.5 # 8.0
Random Numbers
a = rand # Float in [0, 1)
a = rand(10) # Fixnum in 0 <= a < 10
Math
Math.sqrt(4) # 2.0
Parsing Strings to get Numbers
"123".to_i # 123
Integer("123") # 123
"junk".to_i # silently returns 0
Integer("junk") # error
"123junk".to_i # 123
Integer("123junk") # error
" 123 ".to_i # 123
Integer(" 123 ") # 123
"3.1416".to_f # 3.1416
Float("2.718") # 2.718
"2.9979246e5".to_f # 299792.46
Float("6.02e23") # 6.02e23
Formatting Numbers
x = 345.6789
printf("x = %6.2f\n", x) # x = 345.68, prints immediately
sprintf("x = %6.2f\n", x) # returns a String
"x = %6.2f\n" % x # same thing
Strings
Literals
- "abc": Double-quoted strings allow substitution and backslash notation.
- 'abc': Single-quoted strings don't allow substitution and allow backslash notation only for \\ and \'.
- alternate string literals with
%q
(equivalent to single quote) and%Q
(equivalent to double quote):
s1 = %q[As Magritte said, "Ceci n'est pas une pipe."]
s2 = %q*\r is a control-M and \n is a control-J.*
- Here document: create a multi-line string, allowing substitution:
name = "Bill"
letter = <<letter
Dear #{name},
I got your letter!
Sincerely,
Scott
letter
NOTE: if you want to indent the closing "letter", use <<-letter
to start the here document
Concatenation
"foo" "bar" # means "foobar"
"foo" + "bar" # means "foobar"
"foo" << "bar" # means "foobar"
Substitution
"The value is #{ some expression }." # substitute the value of an arbitrary expression
"My name is #{$name}." # substitute the value of a variable
"My name is #$name." # shortcut; only works for global, class, instance variables
str = proc {|x,y,z| "The numbers are #{x}, #{y}, and #{z}" }
s1 = str.call(3,4,5) # The numbers are 3, 4, and 5
# formatted output
name = "Bob"
age = 28
str = sprintf("Hi, %s... I see you're %d years old.", name, age)
str = sprintf("%-20s %3d", name, age)
str = "%-20s %3d" % [name, age] # Same as previous example
# sub and gsub
"abababa".sub("a", "A") # "Abababa"
"abababa".gsub("a", "A") # "AbAbAbA"
"bacon, spam, and eggs".sub(/(\w+), (\w+),/,'\2, \1,') # "spam, bacon, and eggs"
"Don't forget the spam.".sub(/spam/) { |m| m.reverse } # "Don't forget the maps."
Substring
x = "abcdefg"
x[2..4] # "cde" (chars 2 through 4 inclusive)
x[2...4] # "cd" (chars 2 and 3)
x[-3..-2] # "ef"
x[2,4] # "cdef" (extract a string of length 4)
x[-3,2] # "ef"
x[2] # 99 (ascii code for "c")
x[2].chr # "c"
x["bc"] # "bc"
x["cb"] # nil
x[/bc/] # "bc"
x.include? "bc" # true
x["cde"] = "CDE" # x is now "abCDEfg"
x.count("ae") # 2, the number of matching characters
Regular Expression
"I am a leaf on the wind...".scan(/\w+/) # ["I", "am", "a", "leaf", "on", "the", "wind"]
Split
"a b c".split # ["a", "b", "c"]
"a, b, c".split(/, /) # ["a", "b", "c"]
Methods
x = "abcdefg"
x.size # 7
x.length # 7
x.empty? # false
x.upcase # "ABCDEFG"
x.upcase.downcase # "abcdefg"
x.reverse # "gfedcba"
x.delete("ae") # "bcdfg"
"abc\r\n".chomp # "abc", remove trailing newline chars
" \tabc\n".strip # "abc", trim whitespace
ruler = "+" + ("."*4+"5"+"."*4+"+")*3 # "+....5....+....5....+....5....+"
MD5 hash
require 'md5' # already included in Rails
secret = Digest::MD5.hexdigest(password)
Encoding and Decoding base64 Strings
x = "abcdefg"
[x].pack("m") # "YWJjZGVmZw==\n"
[x].pack("m").unpack("m") # ["abcdefg"]
Arrays
Create
x = [1, 2, 3]
x = %w(foo bar baz) # ["foo", "bar", "baz"]
Concatenate
[1, 2, 3] << 4 # [1, 2, 3, 4]
[1, 2] |= [3, 4] # [1, 2, 3, 4]
Iterate
my_array.each do | element |
do something with element
end
or
my_array.each do |e| { do something with e }
or
for e in my_array
do something with e
end
Methods
x = ["a", "b", "c"]
x.length # 3
x.first # "a"
x.last # "c"
x.last(2) # ["b", "c"]
x[0] # "a"
x[0,2] # ["a", "b"]
x[0..2] # ["a", "b", "c"]
x[1..-1] # ["b", "c"]
x.index("a") # 0
x.include? "a" # true
x << "d" # ["a", "b", "c", "d"]
[1, 2, 1].uniq # [1, 2]
x.pop # "c", x is ["a", "b"]
x.push("d") # ["a", "b", "c", "d"]
x.delete("b") # returns "b", leaves x == ["a", "c"]
x.join # "abc"
x.join(", ") # "a, b, c"
x.map{|e| e.upcase} # ["A", "B", "C"]
x.reverse # ["c", "b", "a"]
x.reverse.sort # ["a", "b", "c"]
x.sort_by! {|a| a.name} # sort on name attribute
Set operations
x = ["a", "b", "c"]
y = ["b", "c", "d"]
x & y # ["b", "c"]
x - y # ["a"]
x | y # ["a", "b", "c", "d"]
Range operators
5..10
includes the number 10, but 5...10
does not.
Do not confuse ranges with arrays. These two assignments are entirely different:
x = 1..5
x = [1, 2, 3, 4, 5]
However, there is a convenient method to_a
for converting ranges to arrays.
Array expansion
Also called the "splat" operator
x = [1, 2, 3]
a, b, c = *x # now a is 1, b is 2, c is 3
Hashes
Iterate
x = {:a => 1, :b => 2, :c => 3}
x.each{|k,v| print "(#{k}, #{v})"} # (b, 2)(c, 3)(a, 1)
x.each do |k,v|
...do something with k, v
end
x.each_key{|k| print k} # bca
x.each_value{|v| print v} # 231
Methods
x = {:a => 1, :b => 2, :c => 3}
x.key? :b # true
x.keys # [:b, :c, :a]
x.value? 2 # true
x.values # [2, 3, 1]
x[:a] # 1
x.delete :c # x is {:b=>2, :a=>1}
x = {:b=>2, :a=>1}
y = {:b => 22, :c => 33}
x.merge y # {:b=>22, :c=>33, :a=>1}
x.clear # {}
x.empty? # true
Date and Time
What time is it now?
now = Time.now # Wed Sep 12 11:51:41 -0700 2007
now.year # 2007
now.month # 9
now.day # 12
now.wday # 3
now.hour # 11
now.min # 51
now.sec # 41
Create an arbitrary date:
my_time = Time.local(2007, 9, 11, 17, 30, 13) # Tue Sep 11 17:30:13 -0700 2007
another_date = '2011-09-21'.to_date
yet_another = DateTime.strptime('2015-04-27 4:45 PM', '%Y-%m-%d %H:%M %p')
Date-time arithmetic:
diff = now - my_time # 66088.978569 (in seconds)
diff/(60*60) # 18.3580496025 (in hours)
now + 24*60*60 # Thu Sep 13 11:51:41 -0700 2007
Date-only:
require 'date'
xmas = Date.parse('12/25/2010') # works for usual formats
today = Date.today
today.to_s # "2007-09-12"
yesterday = Date.new(2007, 9, 11)
yesterday.to_s # "2007-09-11"
today - yesterday # Rational(1, 1)
tomorrow = today + 1
tomorrow.to_s # "2007-09-13"