我正在尝试在数组中打印最多加10的元素,但是我收到了这个错误:
8 : 25 : 55 : 5TypeError: nil can't be coerced into Fixnum
这是我的代码:
array = [6, 2, 7, 1, 10, 9, 0, 8, 2, 10, 10, 3, 5, 7, 2, 5, 5, 5]
def print(array)
array.each_with_index.inject(0) do |m,(roll,i)|
if array[i] + array[i+1] == 10
print "#{array[i]} : #{array[i+1]}"
end
end
end
我想要的输出是:
8:2,5:5
我该如何解决这个问题?
答案 0 :(得分:1)
array = [6, 2, 7, 1, 10, 9, 0, 8, 2, 10, 10, 3, 5, 7, 2, 5, 5, 5]
array.flat_map { |n| n == 10 ? [10, 0] : n }.
each_slice(2).
select { |ball1,ball2| ball1 != 10 && ball1+ball2.to_i == 10 }
#=> [[8, 2], [5, 5]]
步骤如下。首先,使用Enumerable#flat_map在每个10
之后插入零(在保龄球中,罢工):
a = array.flat_map { |n| n == 10 ? [10, 0] : n }
#=> [6, 2, 7, 1, 10, 0, 9, 0, 8, 2, 10, 0, 10, 0, 3, 5, 7, 2, 5, 5, 5]
这允许我们使用Enumerable#each_slice将array
划分为成对:
e = a.each_slice(2)
#=> #<Enumerator: [6, 2, 7, 1, 10, 0, 9, 0, 8, 2, 10, 0, 10, 0, 3, 5, 7, 2, 5, 5, 5]
# :each_slice(2)>
我们可以使用Enumerable#entries(或Enumerable#to_a)查看此枚举器将生成的值并传递给select
:
e.entries
#=> [[6, 2], [7, 1], [10, 0], [9, 0], [8, 2], [10, 0], [10, 0], [3, 5],
# [7, 2], [5, 5], [5]]
注意最后一个[5]
的数组。接着,
e.select { |ball1,ball2| ball1 != 10 && ball1+ball2.to_i == 10 }
#=> [[8, 2], [5, 5]]
当生成e
([5]
)的最后一个元素时,select
的块变量计算如下:
ball1, ball2 = [5]
#=> [5]
ball1
#=> 5
ball2
#=> nil
如果上面的块包含&& ball1+ball2 == 10
,则会引发异常(除非在示例的公式中包含array
的最后一个元素是错误的)。这可以用if ball2.nil? ...
语句处理,但我选择简单地将ball2
转换为整数。如果它已经是整数,则返回该值;它等于nil
,nil.to_i #=> 0
。请参阅NilClass#to_i。
答案 1 :(得分:1)
#inject
是一种奇怪的方法,可用于此目的。你写它的方式,nil作为聚合器返回,这就是你没有得到所需结果的原因。删除它,逻辑更清晰:
array = [6, 2, 7, 1, 10, 9, 0, 8, 2, 10, 10, 3, 5, 7, 2, 5, 5, 5]
def print(array)
pairs = []
array.each_with_index do |val, idx|
next if idx == 0
prev_val = array[idx - 1]
curr_total = val + prev_val
if curr_total == 10
pairs << [prev_val, val]
end
end
pairs.map { |pair| pair.join(':') }.join(',')
end