Ruby练习:计算给定范围之间的数组中的数字

时间:2013-05-23 06:42:53

标签: ruby

通过上述练习,在GitHub上找到了这个解决方案。

def count_between arr, lower, upper
  return 0 if arr.length == 0 || lower > upper
  return arr.length if lower == upper
  range = (lower..upper).to_a
  arr.select { |value| range.include?(value) }.length
end

我理解前三行是什么意思,以及为什么他们返回他们所做的值。我想了解的是以下几行代码。

第4行(下面)将“range”定义为变量,并使用lower ... upper作为范围变量(刚发现你不需要在一个范围内放置一个整数值。'。to_a是什么'意思是,似乎无法在ruby文档中找到它,它做了什么?

 range = (lower..upper).to_a

第5行(下面)使用的是一个Array#select方法,如果该值包含在此范围内,则选择此值,然后给出所有选定值的数组#长度,但我不太了解A什么|价值|正在做什么,它意味着什么。 B. range.include?(value)表示此值包含在我假设的范围内。

 arr.select { |value| range.include?(value) }.length

3 个答案:

答案 0 :(得分:6)

实际上,我会对此进行简化:

def count_between arr, lower, upper
  return 0 if lower > upper
  arr.count{|v| (lower..upper).include?(v)}
end
记录了{p> to_a here;它返回一个包含Range中每个元素的Array。但是,在调用to_a之前,没有理由在Range上调用include?

也没有理由对空数组进行特殊处理。

lower等于upper时,返回数组的长度毫无意义。

value是为块调用的值赋予的名称。我认为一个简单的v对于这样一个微不足道的案例更好。

selectarr中的每个值调用块,并返回一个新的Array,其中包含块返回true的元素,因此新数组的长度是匹配值。但是,count存在,并且使用更有意义,因为计数是我们所关心的。

更新:正如@steenslag在评论中指出的那样,可以使用Comparable#between?代替创建要调用include?的范围,这样就无需确保lower小于或等于upper

def count_between arr, lower, upper
  arr.count{|v| v.between?(lower, upper)}
end

答案 1 :(得分:1)

to_a表示转换为数组

irb(main):001:0> (1..5).to_a
=> [1, 2, 3, 4, 5]

select方法将每个元素传递给块,返回一个新数组,其中包含给定块返回true值的所有ary元素。。在您的情况下,它只是检查值是否包含在range数组中。 range是一个不是范围的数组。

## if arr is [1,5] for eg:

irb(main):005:0> [1,5].select {|value| range.include?(value)}
=> [1, 5]
irb(main):006:0> [1,5].select {|value| range.include?(value)}.length
=> 2

所以arr的元素包含在块内的|value|变量中。

答案 2 :(得分:0)

这是一个障碍。

正如文档所说:select“返回一个新数组,其中包含给定块返回true值的所有ary元素。”

因此,对于arr中的每个对象,它将传递给您提供所需代码的块,该代码将返回truefalse,并且select语句将此结果用于将值添加到它返回的数组。之后,在数组上调用length

所以你有一个数组,你过滤数组只包含范围内的数字,然后你取长度 - 有效地计算元素的数量。