Ruby Hash中的字典类

时间:2015-03-12 03:23:38

标签: ruby class testing

我试图从TestFirst.org解决字典问题。目标是让我的代码与测试规范一起使用。

printable方法外,所有测试均通过。我得到了结果,但结果与测试不符。如何匹配我的哈希匹配与@d.printable.should == %Q{[apple] "fruit"\n[fish] "aquatic animal"\n[zebra] "African land animal with stripes"}的顺序?

也有人可以帮我重构,因为我对Ruby很陌生并且对Ruby的快捷方式了解不多?

这是我的代码:

class Dictionary
    #initialization of entries
    def initialize
        @hash = {}
    end

    def entries
        @hash
    end

    #add method to add a keyvalue
    def add(keyvalue)
        if keyvalue.is_a? String
            @hash[keyvalue] = nil
        else
            keyvalue.each do |key, value|
                @hash[key] = value  #create key-value pair in @hash
            end
        end
    end

    #method to get the keywords in the Dictionary
    def keywords
        @key_array = []
        @hash.each {|key,value| @key_array.push(key)}   #push key inside key_array
        return @key_array.sort
    end

    #method to determine if key exists in @hash
    def include?(key)
        yes = false     #assume that the key is not included in @hash
        if key.is_a? String
            @hash.each do |a,b|
                if a == key
                    yes = true  #then if key is included in @hash key then reset it to true
                end
            end
            return yes  #return yes
        end

        #or alternatively (if I figured this out sooner) one line @hash.has_key?(key)? true: false
    end

    #method to find a matching keyword
    def find(str)
        found_hash = {} #start with an empty hash
        if str.is_a? String
            @hash.each do |key,value|
                if key[0...str.length] == str   #key[0...str.length] equates to characters from length 0 to str.length
                    found_hash[key] = value     #create new hash if statement is true
                end
            end
            return found_hash
        end
    end

    #method to print
    def printable
        str = ""
        @hash.each do |key, value|
            str = str+"["+key+"]"+" "+"\""+value+"\"\n"
        end
        return str

    end


end

这是我的测试规范:

require '11_dictionary'

describe Dictionary do
  before do
    @d = Dictionary.new
  end

  it 'is empty when created' do
    @d.entries.should == {}
  end

  it 'can add whole entries with keyword and definition' do
    @d.add('fish' => 'aquatic animal')
    @d.entries.should == {'fish' => 'aquatic animal'}
    @d.keywords.should == ['fish']
  end

  it 'add keywords (without definition)' do
    @d.add('fish')
    @d.entries.should == {'fish' => nil}
    @d.keywords.should == ['fish']
  end

  it 'can check whether a given keyword exists' do
    @d.include?('fish').should be false
  end

  it "doesn't cheat when checking whether a given keyword exists" do
    @d.include?('fish').should be false # if the method is empty, this test passes with nil returned
    @d.add('fish')
    @d.include?('fish').should be true # confirms that it actually checks
    @d.include?('bird').should be false # confirms not always returning true after add
  end

  it "doesn't include a prefix that wasn't added as a word in and of itself" do
    @d.add('fish')
    @d.include?('fi').should be false
  end

  it "doesn't find a word in empty dictionary" do
    @d.find('fi').should be_empty # {}
  end

  it 'finds nothing if the prefix matches nothing' do
    @d.add('fiend')
    @d.add('great')
    @d.find('nothing').should be_empty
  end

  it "finds an entry" do
    @d.add('fish' => 'aquatic animal')
    @d.find('fish').should == {'fish' => 'aquatic animal'}
  end

  it 'finds multiple matches from a prefix and returns the entire entry (keyword + definition)' do
    @d.add('fish' => 'aquatic animal')
    @d.add('fiend' => 'wicked person')
    @d.add('great' => 'remarkable')
    @d.find('fi').should == {'fish' => 'aquatic animal', 'fiend' => 'wicked person'}
  end

  it 'lists keywords alphabetically' do
    @d.add('zebra' => 'African land animal with stripes')
    @d.add('fish' => 'aquatic animal')
    @d.add('apple' => 'fruit')
    @d.keywords.should == %w(apple fish zebra)
  end

  it 'can produce printable output like so: [keyword] "definition"' do
    @d.add('zebra' => 'African land animal with stripes')
    @d.add('fish' => 'aquatic animal')
    @d.add('apple' => 'fruit')
    @d.printable.should == %Q{[apple] "fruit"\n[fish] "aquatic animal"\n[zebra] "African land animal with stripes"}
  end
end

1 个答案:

答案 0 :(得分:1)

我认为你可以这样做。

def printable
  keywords.map { |keyword| "[#{keyword}] #{@hash[keyword]}" }.join("\n")
end

<强>重构

这就是我编写代码的方式。请注意,我没有运行规格!查看我使用的方法很有趣。

class Dictionary
  attr_reader :entries

  def initialize
    @entries = {}
  end

  def add(key_and_value)
    if key_and_value.respond_to(:each_pair)
      key_and_value.each_pair do |key, value|
        entries.update(key => value)
      end
    else
      entries.update(key_and_value => nil)
    end
  end

  def keywords
    entries.keys.sort
  end

  def include?(key)
    entries.key?(key)
  end

  def find(prefix)
    matching_keys = entries.keys.select { |key| key.start_with?(prefix) }
    entries.select { |key, _| matching_keys.include?(key) }
  end

  def printable
    keywords.map { |key| "[#{key}] #{entries[key]}" }.join("\n")
  end
end