15 May 2011

Find

#File IO without block
#f = File.new("testfile", "r")
#f.close

#File IO with block, implicit call to f.close
#File.open("testfile", "r") do |aFile| end

#Hash to array
h = { 1 => 2, "cat" => "tom" }
a = h.to_a

#Array to hash
a = (1..10).to_a
h = Hash[a.map { |i| [i, i * 2] } ]

#Iterate through a hash
h.each { |i| puts "#{i[0]} : #{i[1]}" }

#Use array as stack
a.push 19
a.pop

#Arrays can be used as: stacks, sets, queues, dequeues, and fifos

Do

Print the content of an array of sixteen numbers, four numbers at a time, using just each. Now, do the same with each_slice in Enumerable:

#Using each (interesting fact: there is a closure on a here)
a.each { |i| if i % 4 == 0 then puts "#{a[i-4..i-1]}" end }

#Using each_slice 
a.each_slice(4) { |s| puts "#{s}" }

Rewrite the Tree class so it can be initialized with a nested structure with hashes and arrays:

#Initial code from the book
class Tree
  attr_accessor :children, :node_name
  
  def initialize(name, children=[])
    @children = children
    @node_name = name
  end
  
  def visit_all(&block)
    visit &block
    @children.each { |c| c.visit_all &block }
  end
  
  def visit(&block)
    block.call self
  end
end

t = Tree.new("Ruby", [Tree.new("Gem")])
t.visit_all { |t| puts "#{t.node_name}" }

Starting from that, this is what we want to be able to write:

Tree.new({ 'grandpa' => { 'dad' => { 'child 1' => {}, 'child 2' => {} }, 'uncle' => { 'child 3' => {}, 'child 4' => {} } } })

And here is my solution to it:

class Tree
  attr_accessor :children, :node_name
  
  def initialize(structure)
    structure.each do
      |key, value|
      @node_name = key
      @children = value.to_a.map { |e| Tree.new({ e[0] => e[1] }) }
    end
  end
  
  def visit_all(&block)
    visit &block
    @children.each { |c| c.visit_all &block }
  end
  
  def visit(&block)
    block.call self
  end
end

t = Tree.new({ 'grandpa' => { 'dad' => { 'child 1' => {}, 'child 2' => {} }, 'uncle' => { 'child 3' => {}, 'child 4' => {} } } })
t.visit_all { |t| puts "#{t.node_name}" }

Write a simple grep that will print the lines of a file having any occurrences of a phrase anywhere in that line. Use Regular Expressions and include line numbers:

regex = Regexp.new('sit amet')
ln = 0

IO.foreach("TestGrep.txt") do |line|
  ln = ln + 1
  puts "#{ln}: #{line}" if regex.match(line)
end


blog comments powered by Disqus