2016-07-07 35 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