2014-03-06 172 views
0

我试图自动化测试。有没有更好的方法来解决这个问题?我试图创建一个只包含三个数的倍数的数组。红宝石:生成阵列

(1...100).each_with_object([]) { |i, a| a << i if i % 3 == 0 }.reject { |i| i % 5 == 0 } 
+0

我不太清楚你后有什么一连串的数字,但每个可以被3整除的数字可以被另一个数字整除。如果'x'均匀地除以3来给出'y','x'将被均匀地除以'y'得到3.除了3和9之外没有数字符合您的标准是“3的倍数” “这就是假设你会忽略每个数字都是1的倍数。 – meagar

+0

我有一个采访,涉及与RSpec做FizzBu​​zz。我想出了一个很好的解决方案,但是我没有时间来自动化测试。我希望确保我创建的这个数组只能打印出“Fizz”,仅用于三个和三个的倍数。我会做同样的事情五倍的倍数。而不是说:'''[3,6,9] .each {| x | expect(fizzbuzz(x))。to eq('Fizz')}' – theGrayFox

+0

@meagar:“(三的倍数),没有别的”。不是“(三不是其他)的倍数”。 :) – Amadan

回答

1

我试图创建一个只包含三个,没有别的倍数的数组。

使用Numeric#step枚举:

3.step(100, 3).to_a 

创建三个的倍数高达100

你的代码似乎有太多过滤掉五岁以下儿童的附加效果。您可以筛选出来:

3.step(100, 3).reject { |i| i % 5 == 0 } 

或者你也可以做一些完全不同的:

require 'set' 
((1..100).to_set - 3.step(100, 3) - 5.step(100, 5)).to_a 

比拒绝的方式更清晰一点,但可能有点慢。

+0

我从来没有用过一步,很酷。你教给我一些新的东西。 :-) – theGrayFox

+0

'(1..100).to_set'也可以写成'Set.new(1..100)'。我不知道'to_set'可用于将Enumerable对象(因此Enumerator对象,例如'3.step(100,3)',因为Enumerator包含Enumerable)转换为集合,但[它确实](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/set/rdoc/Set.html),但我仍然不明白为什么没有'Enumerable#to_set' 。我只找到'Set.to_set'。 –

2

为什么不map数字1至33由每个由三个相乘,然后拒绝的5倍数?

(1..33).map { |i| i * 3 }.reject { |i| i % 5 == 0 } 
+0

我完全忘了地图!感谢您的洞察力。 – theGrayFox

+0

+1对于地图和降低枚举数。甚至可以做'(1.33).map {| i |我* 3除非我* 3%5 == 0} .compact!' – engineersmnky

0

一百万和1红宝石

(1..100).collect{|i| i if i % 3 == 0 && i % 5 != 0}.compact! 
(1..100).select{|i| i if i % 3 == 0 && i % 5 != 0} 

这里迭代的方式是另一个之一,它读取真的很好

(1..100).find_all{|i| i % 3 ==0 && i % 5 !=0} 
+0

'collect'在这里并不适合;使用'select'或'reject' – meagar

+0

够公平的,因为我必须调用'compact!'加上'select' – engineersmnky