2016-07-07 26 views
2

我有一個具有多個值幾個按鍵和一對夫妻帶着一個值YAML文件:閱讀YAML使用Ruby,意外的返回類型

inbox: 
    paul: 'PHILADELPHIA-RO-ADMIN' 
    tanny: 'PA-C-INDIANA-ADMIN' 
    mary: 
      - 'MD-C-LAUREL-ADMIN' 
      - 'MD-E-BALTIMORE-ADMIN' 
      - 'MD-R1-CAMBRIDGE-ADMIN' 
      - 'MD-R2-BELAIR-ADMIN' 
      - 'MD-R4-LAUREL-ADMIN' 
      - 'MD-R5-HAGERSTWN-ADMIN' 
    mike: 
      - 'VA-E-Richmond-Admin' 
      - 'VA-Richmond-Admin' 
      - 'VA-Manassas-Admin' 
      - 'VA-Norfolk-Admin' 
      - 'VA-Roanoke-Admin' 
      - 'VA-Verona-Admin' 

什麼我試圖做的是,如果該鍵有多於一個值輸出鍵的值不止一個,但如果該鍵只有一個值,則只輸出該值。我試圖使用Array.count功能來做到這一點,我已經遇到在那裏,如果數組只有一個值它計算的關鍵內部字符量的問題,例如:

require 'yaml' 

POC = YAML.load_file('test.yml') 

def get_poc(name) 

    data = POC['inbox'][name.downcase] 
    puts data.count 
    if data.count == 1 
    POC['inbox'][name] 
    else 
    puts "Multiple inboxes found for #{name.capitalize.chomp}" 
    data.each.with_index(1) do |str, i| 
     puts "#{i}. #{str}" 
    end 
    puts 'One of the above inboxes is the correct inbox for this ticket.' 
    end 
end 

當這運行在IRB:

irb(main):020:0> get_poc('mary') 
6 
Multiple inboxes found for Mary 
1. MD-C-LAUREL-ADMIN 
2. MD-E-BALTIMORE-ADMIN 
3. MD-R1-CAMBRIDGE-ADMIN 
4. MD-R2-BELAIR-ADMIN 
5. MD-R4-LAUREL-ADMIN 
6. MD-R5-HAGERSTWN-ADMIN 
One of the above inboxes is the correct inbox for this ticket. 
=> nil 
irb(main):021:0> get_poc('paul') 
21 
ArgumentError: wrong number of arguments (given 0, expected 1+) 
     from (irb):10:in `count' 
     from (irb):10:in `get_poc' 
     from (irb):21 
     from C:/Ruby23/bin/irb.cmd:19:in `<main>' 
irb(main):022:0> 

看來,它適用於多個值,然而,當只有一個給它似乎會數由字符全長價值的價值。

我也使用Array.length方法嘗試:

require 'yaml' 

    POC = YAML.load_file('test.yml') 

    def get_poc(name) 

     data = POC['inbox'][name.downcase] 
     puts data.length 
     if data.length == 1 
     POC['inbox'][name] 
     else 
     puts "Multiple inboxes found for #{name.capitalize.chomp}" 
     data.each.with_index(1) do |str, i| 
      puts "#{i}. #{str}" 
     end 
     puts 'One of the above inboxes is the correct inbox for this ticket.' 
     end 
    end 

同樣的問題,不同的錯誤:

irb(main):040:0> get_poc('mary') 
6 
Multiple inboxes found for Mary 
1. MD-C-LAUREL-ADMIN 
2. MD-E-BALTIMORE-ADMIN 
3. MD-R1-CAMBRIDGE-ADMIN 
4. MD-R2-BELAIR-ADMIN 
5. MD-R4-LAUREL-ADMIN 
6. MD-R5-HAGERSTWN-ADMIN 
One of the above inboxes is the correct inbox for this ticket. 
=> nil 
irb(main):041:0> get_poc('paul') 
21 
Multiple inboxes found for Paul 
NoMethodError: undefined method `each' for "PHILADELPHIA-RO-ADMIN":String 
     from (irb):34:in `get_poc' 
     from (irb):41 
     from C:/Ruby23/bin/irb.cmd:19:in `<main>' 
irb(main):042:0> 

我怎樣才能獲得方法只能算值作爲一個元素?

回答

2

問題的根源在於POC['inbox'][name.downcase]將返回不同的對象:

  1. 當一個單一的項目,則返回String
  2. 返回列表時,Array

換句話說:

POC['inbox']['mary'].class 
#=> Array 
POC['inbox']['paul'].class 
#=> String 

count爲這些2類定義不同。

要檢查是否有一個項目,您可以:

  1. 檢查,如果數據是String
  2. 如果不是String,檢查count爲1(即在的情況下,一個名單被使用,但它只有1項)

更新if條件是:

def get_poc(name) 
    data = POC['inbox'][name.downcase] 

    if data.kind_of?(String) || data.count == 1 
    POC['inbox'][name] 
    else 
    puts "Multiple inboxes found for #{name.capitalize.chomp}" 
    data.each.with_index(1) do |str, i| 
     puts "#{i}. #{str}" 
    end 
    puts 'One of the above inboxes is the correct inbox for this ticket.' 
    end 
end 
+0

唯一的問題是count不返回1,它返回字符串的長度。但爲什麼它返回一個'String'而不是'Array'? – JohnDoeYo

+1

'count'和'length'對'Strings'具有不同的含義,所以不會返回預期的1.返回String,因爲這是YAML文件中定義的內容。包含單個項目的列表需要是虛線列表。 –

2

您沒有一致地使用yml文件,因此不會得到一致的結果。如果你想Paul是一個單元陣列,你需要...

inbox: 
    paul: 
    - 'PHILADELPHIA-RO-ADMIN' 
... 

或者你可以通過改變只有一行修復代碼:

data = [POC['inbox'][name.downcase]].flatten 

這樣,你總是得到一個數組,即使鑰匙只有一個元素,返回值是字符串。

+0

我總是受到數組總是從'yaml'返回的印象。太棒了,謝謝。 – JohnDoeYo