0

我想要做的是创建一个可以将数组作为参数的方法。数组中应该有一些数字。该方法将返回数组包含其中每个数字的次数。我知道可能有很多方法可以做到这一点,但如果人们能帮助我理解为什么我的方法不起作用而不是仅仅建议我做一些完全不同的事情,我将不胜感激。

所以我开始尝试这个方法

def score (dice)
    dice.each do |die|
        x = /(die)/.match(dice.to_s).length
    end
    x
end

并调用它score ([5])期望得到 1 的输出。但是,我得到

NoMethodError: undefined method `length' for nil:NilClass
    from t2.rb:22:in `block in score'
    from t2.rb:21:in `each'
    from t2.rb:21:in `score'
    from (irb):2
    from /home/macs/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'

我也尝试过稍微改变 match 语句(去掉to_s),所以它是

 def score (dice)
        dice.each do |die|
            x = /(die)/.match(dice).length
        end
        x
    end

并用score ([5])我得到

TypeError: no implicit conversion of Array into String
    from t2.rb:22:in `match'
    from t2.rb:22:in `block in score'
    from t2.rb:21:in `each'
    from t2.rb:21:in `score'
    from (irb):2
    from /home/macs/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'

真的不知道我应该如何完成这种匹配。

4

6 回答 6

2

在这一行

/(die)/.match(dice.to_s).length

如果您传递的参数与正则表达式不匹配,则该方法match返回,这会导致此错误nil

nil.length
# => NoMethodError: undefined method `length' for nil:NilClass

该方法将返回数组包含其中每个数字的次数。

你可以试试这个

a = [1,1,1,2,2,1,3]
a.uniq.map { |x| a.count(x) }
# => [4, 2, 1]
a.uniq.map { |x| {x => a.count(x)} }
# => [{1=>4}, {2=>2}, {3=>1}]
于 2013-10-28T08:17:55.283 回答
1

如果人们能帮助我理解为什么我的方式不起作用,我将不胜感激......

/(die)/创建一个Regexp,一个可以与字符串匹配的模式。您的模式匹配并捕获die.

Regexp#matchMatchData如果有匹配则返回一个对象:

/(die)/.match('a string with die')  #=> #<MatchData "die" 1:"die">
#          here's the match: ^^^

或者nil如果没有匹配:

/(die)/.match('a string with dice') #=> nil

您不是在使用字符串,而是在使用整数数组。您可以使用以下方法将此数组转换为字符串Array#to_s

dice = [5]
dice.to_s  #=> "[5]"

此字符串不包含die,因此match返回nil

/(die)/.match("[5]") #=> nil

跟注nil.length然后加注NoMethodError.

“按原样”传递数组也不起作用,因为match需要一个字符串:

/(die)/.match([5]) #=> TypeError: no implicit conversion of Array into String

在这里使用 aRegexp是行不通的,你必须以另一种方式解决这个问题。

于 2013-10-28T08:55:16.663 回答
1

这可能是解决问题的最红宝石方法:

a = [1,1,1,2,2,1,3]
p Hash[a.group_by{|x|x}.map{|key, val| [key,val.size]}]
#=> {1=>4, 2=>2, 3=>1}
于 2013-10-28T09:48:37.230 回答
1

如果要计算数组中每个元素的出现次数,则可以执行以下操作

def score (dice)
    count_hash = {}
    dice.uniq.each do |die|
      count_hash[die] = dice.count(die)
    end
    count_hash
end
于 2013-10-28T08:14:40.607 回答
0

一个可以帮助您实现逻辑的示例

a = [2,3,2,8,3]
a.uniq.each {|i| print i, "=>", a.to_s.scan(/#{i}/).length, " times \n" } #=> this works but ugly.
a.uniq.each {|i| print i, "=>", a.count(i), " times \n" } #=> borrowed from one of the answers.

2=>2 times
3=>2 times
8=>1 times
于 2013-10-28T08:27:35.290 回答
0

您会遇到错误,因为在这两种情况下,您都试图将字符串 (5) 与错误的内容匹配。

这试图与转换为字符串die的整个数组匹配:dice

dice.each do |die|
  x = /(die)/.match(dice.to_s).length
end

这试图diedice数组本身匹配:

dice.each do |die|
  x = /(die)/.match(dice).length
end
于 2013-10-28T08:27:59.087 回答