在Ruby中使用多个对象的Enumerables

时间:2017-02-19 21:40:04

标签: ruby

我正在玩Ruby on Codecademy并且不确定如何进一步减少这种情况。目前的代码是:

can_ride_(1..3).each {|x| group_(x).select(&over_4_feet)}

我想知道我怎么能得到这样的东西:

{{1}}

当对象持有像这样的可重复模式时,是否有可能以这种方式使用Enumerable方法?如果它是一个正则表达式,我不介意,但对可能推荐的模式感到好奇。

2 个答案:

答案 0 :(得分:1)

您可以拥有一组数组,而不是每个组都有一个变量,因此您可以map将其添加到另一个数组中,在每个元素中应用select

groups = []

groups.push [4.1, 5.5, 3.2, 3.3, 6.1, 3.9, 4.7]
groups.push [7.0, 3.8, 6.2, 6.1, 4.4, 4.9, 3.0]
groups.push [5.5, 5.1, 3.9, 4.3, 4.9, 3.2, 3.2]

over_4_feet = Proc.new { |height| height >= 4 }

can_ride = groups.map { |group| group.select(&over_4_feet) }

puts can_ride

答案 1 :(得分:1)

这是一个非常糟糕的问题(CodeAcademy上的问题)因为代码公然不代表现实世界。它的设计目的是围绕行为定义对象具有挑战性。也就是说,这是另一种纯粹学术性的方法 - 不要在生产代码中这样做:

group_1 = …
group_2 = …
group_3 = …

can_ride_1 = can_ride_2 = can_ride_3 = nil

1.upto(3) do |i|
  group = binding.local_variable_get("group_#{i}")
  binding.local_variable_set("can_ride_#{i}", group.select { |v| v >= 4 })
end

这是对此的另一种利用:

eligible_riders = -> (group_num) do
  group = binding.local_variable_get("group_#{group_num}")
  group.select { |v| v >= 4 }
end

can_ride_1 = eligible_riders[1]
can_ride_2 = eligible_riders[2]
can_ride_3 = eligible_riders[3]

更合适的方法是提取一个对象来代表每个group

class Group < Array
  def select_eligible
    select { |v| v >= 4 }
  end
end

group_1 = Group.new [1, 2, 3, 4, 5]
group_2 = Group.new [1, 2, 3, 4, 5]
group_3 = Group.new [1, 2, 3, 4, 5]

eligible = [group_1, group_2, group_3].map &:select_eligible
can_ride_1, can_ride_2, can_ride_3 = *eligible

或者你可以使用你拥有的proc来利用这些splat增强功能:

can_ride_1, can_ride_2, can_ride_3 = *[group_1, group_2, group_3].map do |g|
  g.select &over_4_feet
end