我想在不使用索引的情况下获取颜色 blue 之后要打印的颜色列表。我这样做了
colors = ["Red", "Blue", "Green", "Purple", "White", "Black"]
colors.each { |item| print item if item > "Blue" }
但输出是
红绿紫白色
有谁知道为什么?
答案 0 :(得分:4)
问题"为什么"已经在davidhu2000的评论中回答:
因为您打印的是蓝色后按字母顺序排列的所有项目
如果您不想使用索引,那么您可以使用带有帮助变量的解决方案:
colors = ["Red", "Blue", "Green", "Purple", "White", "Black"]
blue_found = false
colors.each { |item|
if blue_found
print item
else
blue_found ||= item == "Blue"
end
}
如果你喜欢单行,你可以使用
blue_found ? (print item) : (blue_found ||= item == "Blue" )
另一种可能性:
colors = ["Red", "Blue", "Green", "Purple", "White", "Black"]
blue_found = false
colors.each { |item|
print item if blue_found
blue_found ||= item == "Blue"
}
我很好奇,为什么你不想使用索引,所以我在你的问题之外做了一些研究。
带索引的解决方案是:
colors.each_with_index { |item,i|
print item if i > colors.index("Blue")
}
index
- 方法可能需要更多运行时。为了测试它,我做了一个基准测试:
colors = ["Red", "Blue", "Green", "Purple", "White", "Black"]
require 'benchmark'
TEST_LOOPS = 100_000
def action(item)
#Just a no-action.
end
Benchmark.bm(10) {|b|
b.report('test/variable') {
TEST_LOOPS.times {
blue_found = false
colors.each { |item|
action(item) if blue_found
blue_found ||= item == "Blue"
}
} #Testloops
} #b.report
b.report('test/index') {
TEST_LOOPS.times {
colors.each_with_index { |item,i|
action(item) if i > colors.index("Blue")
}
} #Testloops
} #b.report
b.report('test/index2') {
TEST_LOOPS.times {
index_blue = colors.index("Blue")
colors.each_with_index { |item,i|
action(item) if i > index_blue
}
} #Testloops
} #b.report
b.report('test/dogbert') {
TEST_LOOPS.times {
# Drop all items until you find "Blue", then drop the "Blue".
colors.drop_while { |item| item != "Blue" }.drop(1).each do |item|
action(item)
end
} #Testloops
} #b.report
b.report('test/pjs') {
TEST_LOOPS.times {
after_blue = colors.dup
loop do
break if after_blue.shift == 'Blue'|| after_blue.length < 1
end
after_blue.each{|item| action(item) }
} #Testloops
} #b.report
} #Benchmark
结果:
user system total real
test/variable 0.187000 0.000000 0.187000 ( 0.179010)
test/index 0.250000 0.000000 0.250000 ( 0.254015)
test/index2 0.140000 0.000000 0.140000 ( 0.136008)
test/dogbert 0.110000 0.000000 0.110000 ( 0.111006)
test/pjs 0.327000 0.000000 0.327000 ( 0.332019)
因此带有帮助变量的版本(正如预期的那样)更快。但是如果你在循环之外定义一次索引,那么带索引(test / index2)的解决方案几乎和测试/变量一样快。
免责声明:我对更快的解决方案没有多少想法。所以也许有一种更有效的方式。感谢dogbert的暗示。
答案 1 :(得分:2)
使用@ knut&#39; test/variable
基准测试的另一种方法是:
def values_after(target, arr)
result = arr.dup
loop do
break if result.shift == target || result.length < 1
end
result
end
colors = ['Red', 'Blue', 'Green', 'Purple', 'White', 'Black']
puts *values_after('Blue', colors)
# Or, if you prefer all on one comma-separated line:
# puts values_after('Blue', colors).join(', ')
如果|| result.length < 1
不是target
中的元素,则arr
是一个防止无限循环的保护子句。
答案 2 :(得分:0)
虽然已经出现的两个答案给出了正确的答案,但我会使用更具功能性的风格,在我看来更具可读性。
colors = ["Red", "Blue", "Green", "Purple", "White", "Black"]
# Drop all items until you find "Blue", then drop the "Blue".
colors.drop_while { |item| item != "Blue" }.drop(1).each do |item|
puts item
end
由于@knut提到了基准测试,这段代码只比@ knut的test/variable
基准测试慢一点:
user system total real
test/variable 0.790000 0.000000 0.790000 ( 0.790960)
test/drop 0.900000 0.000000 0.900000 ( 0.898137)