0

I've looked at everything from the Ruby docs on struct, map, array & hash; but for whatever reason haven't grasped HOW to do this. I have two questions.

  1. What's a good way to see if an array and a hash have a value in common?
  2. From a hash, how could I find a value and "automatically" take it's key (or viceversa) and include them in a new instance of something else (e.g. Pair.new)?

I saw this SO response, but it wasn't much help...Learn Ruby Hard Way ex. 48

Also looked at this too, but it didn't work & Zed says to use map func... Using Ruby, what is the most efficient way to check if any key in a hash matches any values within an Array

The exercise instructions can be found here. Ruby The Hard Way EX.48 Instructions

MY CODE (try#2080)

class Lexicon

Pair = Struct.new(:token, :key)

def scan(stuff)
    @words = stuff.split(" ")
    return analyze
end

def analyze

    hash = { :direction => "north", :direction => "south", 
            :direction => "east", :direction => "west", :verb => "go",  
                                 :verb => "stop"}

    @words.map do |word|
        if word == hash[:direction]
        #i need something here that says if word matches a value in hash... 
        #assign matching key/value to a new instance of Pair
            Pair.new(word)
        else
                            *#puts to see if anything is sticking* 
            puts "Oh god its not working #{word}"
            puts Pair[]
            puts hash[:direction]
           end
       end
  end
end

a = Lexicon.new()
a.scan("north mama jeffrey homie")

TERMINAL

$ ruby lexicon.rb
Oh god its not working north
#<struct Lexicon::Pair token=nil, key=nil>
west

Oh god its not working mama
#<struct Lexicon::Pair token=nil, key=nil>
west

Oh god its not working Jeffrey
#<struct Lexicon::Pair token=nil, key=nil>
west

Oh god its not working homie
#<struct Lexicon::Pair token=nil, key=nil>
west

MY CODE #2081 Same as above but,

   hash.each do |k, v|
      if v == @words
      #i need something here that says if word matches a value in hash... 
      #assign matching key/value to a new instance of Pair
        Pair.new(k,v)
      else
        puts "Oh god its not working"
        puts Pair[]
        puts hash[:direction]
        puts @words
      end
   end

TERMINAL

Oh god its not working
#<struct Lexicon::Pair token=nil, key=nil>
...
...
1
  • 2
    For your definition of hash, irb will say: hash => {:direction=>"west", :verb=>"stop"}. Do you see why? Commented Nov 16, 2013 at 22:59

3 Answers 3

2

You've got several issues here. Most importantly, your hash is not functional; hashes are built on key-value pairs with unique keys, so your hash is actually the same as the following:

hash = { :direction => "west", :verb => "stop"}

You would probably be better off swapping the key-value pairs in your hash as follows:

hash = { "north" => :direction, "south" => :direction, 
        "east" => :direction, "west" => :direction, "go" => :verb,  
                             "stop" => :verb }

@words.map do |word|
  hash.keys.include?(word) ? Pair.new(hash[word], word) : Pair.new(:error, word)
end
Sign up to request clarification or add additional context in comments.

2 Comments

thanks @elreimundo! is there an elegant way I could accomplish the same without swapping the key-value pairs?
Why hash.keys.include?(word) rather than hash.key?(word)?
0
def have_common_value?(array, hash)
  hash.values.any? { |v| array.include? v }
end

def get_pair_from_value(hash, value)
  hash.find { |k,v| v == value }
end

1 Comment

Thanks @Amit I'm going to try these too.
0

A hash can only have one unique key per value, therefore, part of your problem is that the hash you generate above will only return one :direction and one :location.

This should help get you closer to what you're looking for:

class Lexicon

  Pair = Struct.new(:token, :key)

  def scan(stuff)
    @words = stuff.split(" ")
    return analyze
  end

  def analyze
    hash = { :directions => { :north => "north", :south => "south", :east => "east", :west => "west" },
             :actions => { :verb => "go", :verb => "stop" } }

    @words.map do |word|
      if hash[:directions].values.include?(word)
        Pair.new(word)
      else
        puts "Oh god its not working #{word}"
        puts Pair[]
        puts hash[:directions]
      end
    end
  end
end

a = Lexicon.new()
a.scan("north mama jeffrey homie")

1 Comment

Thanks @CDub but I'd need to incorporate :directions for each matching value and pass that to Pair (e.g Pair.new (:directions,'north'))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.