foo bar不能打印正确的输出

时间:2017-10-25 10:46:32

标签: ruby fizzbuzz

目前我的代码将显示1到100但实际上不会打印出case语句,当它可以被3或5或两者整除时....我在这里做错了什么?

def display(item_count)
  n = 1  
  while n <= item_count
    case n
    when n % 3 == 0 
      puts "foo"
    when n % 5 == 0
      puts "bar"
    when (n % 3 ==0 && n % 5 == 0) 
      puts "foobar"
    else
      puts "#{n}"
    end #--  case end stmt
    n = n + 1
  end #while end statement
end #end satement for metod

puts " How many items do you want to see"
item_count = gets.chomp.to_i
puts "#{display(item_count)}"

4 个答案:

答案 0 :(得分:1)

case expression使用when(在大多数情况下与===相同)将您提供的参数与每个==表达式进行比较。所以你的代码大致相当于

if (n % 3 == 0) === n
  puts "foo"
elsif (n % 5 == 0) === n
  puts "bar"
elsif (n % 3 == 0 && n % 5 == 0) === n
  puts "foobar"
else
  puts "#{n}"
end

所有when个表达式都会返回truefalse,因此每个案例都会失败,您最终会进入else。只需使用此if格式代替case,您就可以执行您想要的操作(尽管您需要重新排列条件才能获得正确的输出)。

答案 1 :(得分:1)

你可以在没有参数的ruby中使用case语句。 when子句仍然必须返回true或false。

case
when true
  puts 'this happens'
when false
  puts 'this does not happen'
end

因此,如果您只是更改

,原始帖子中的代码将起作用(至少是案例陈述)
case n

case

并将'foobar'测试移到“when”列表的顶部。我的另一个答案也使用了这个结构,但是消除了堆栈操作并产生了一个可存储/可传输的对象,而不仅仅是显示结果。

注意:调用零?对象上的方法比将它与文字0比较要快。(x.zero?比x == 0更快)。

答案 2 :(得分:0)

print "Enter amount of times> "
(1..gets.to_i).each do |i|
  puts(
    "".tap do |res|
      res << "foo" if (i % 3).zero?
      res << "bar" if (i % 5).zero?
      res << i.to_s if res.empty?
    end)
end

答案 3 :(得分:-1)

显示某事是一回事;具有在存储器中可用于进一步使用的功能的结果,例如通过网络连接或存储器的传输,是另外的。在ruby中,一切都是一个对象,所以你应该对对象进行操作。这就是红宝石的制作方式。

编辑以解决多次循环和可读性问题。

我原来被谴责为不可读,然后有人想出了一个使用lambda文字和猴子修补的monadic解决方案。即使是经验丰富的程序员也会被要求遵循其逻辑,并且解释器中涉及的堆栈操作无论如何都会将可扩展性抛到窗外。单循环中的程序块解决所有这些问题,而不是迂腐。 “可读”也暗示“可以理解”。

在ruby&gt; = 2.4中,不需要冻结字符串文字;它们应该被自动冻结,但由于单循环解决方案是为了解决可伸缩性(想象一下它可以调用一百万次),因此不应忽视这种优化。此外,我已将其缩减为块内的单个条件语句,这意味着更高的可伸缩性。

print 'How many items do you want to see: '.freeze

list = (1..gets.to_i).collect do |i|
  div_by_3 = (i % 3).zero?
  div_by_5 = (i % 5).zero?
  case 
    when div_by_3 && div_by_5
      :foobar
    when div_by_3
      :foo
    when div_by_5
      :bar
    else
     i
  end
end

puts list.to_s

输出:

How many items do you want to see: 50
[1, 2, :foo, 4, :bar, :foo, 7, 8, :foo, :bar, 11, :foo, 13, 14, :foobar, 16, 17, :foo, 19, :bar, :foo, 22, 23, :foo, :bar, 26, :foo, 28, 29, :foobar, 31, 32, :foo, 34, :bar, :foo, 37, 38, :foo, :bar, 41, :foo, 43, 44, :foobar, 46, 47, :foo, 49, :bar]