我正在尝试创建一个脚本来浏览索引,查看每个页码,然后告诉我该条目的书的哪一章。这是我正在做的事情的近似值:
@chapters = {
1 => "introduction.xhtml",
2..5 => "chapter1.xhtml",
6..10 => "chapter2.xhtml",
11..18 => "chapter3.xhtml",
19..30 => "chapter4.xhtml" }
def find_chapter(number)
@chapters.each do |page_range, chapter_name|
if number === page_range
puts "<a href=\"" + chapter_name + "\page" + number.to_s + "\">" + number.to_s + </a>"
end
end
end
find_chapter(1)
将吐出我想要的字符串,但find_chapter(15)
不会返回任何内容。是不是可以像这样使用范围?
答案 0 :(得分:25)
您可以使用哈希键的范围,您可以使用select
这样轻松查找键:
@chapters = { 1 => "introduction.xhtml", 2..5 => "chapter1.xhtml",
6..10 => "chapter2.xhtml", 11..18 => "chapter3.xhtml",
19..30 => "chapter4.xhtml" }
@chapters.select {|chapter| chapter === 5 }
#=> {2..5=>"chapter1.xhtml"}
如果您只想要章节名称,只需添加.values.first
,如下所示:
@chapters.select {|chapter| chapter === 9 }.values.first
#=> "chapter2.xhtml"
答案 1 :(得分:7)
当然,只需反转比较
if page_range === number
喜欢这个
@chapters = {
1 => "introduction.xhtml",
2..5 => "chapter1.xhtml",
6..10 => "chapter2.xhtml",
11..18 => "chapter3.xhtml",
19..30 => "chapter4.xhtml" }
def find_chapter(number)
@chapters.each do |page_range, chapter_name|
if page_range === number
puts chapter_name
end
end
end
find_chapter(1)
find_chapter(15)
# >> introduction.xhtml
# >> chapter3.xhtml
它的工作方式是这样的,因为Range上的===
方法具有特殊行为:Range#===。如果您先放置number
,则会调用Fixnum#===
,它会以数字方式比较值。范围不是数字,因此它们不匹配。
答案 2 :(得分:5)
正如@Sergio Tulentsev所示,它可以完成。然而,通常的方法是使用case when
。它更灵活,因为您可以在then
子句中执行代码,并且可以使用else
部分处理未处理的所有内容。它使用相同的===
方法。
def find_chapter(number)
title = case number
when 1 then "introduction.xhtml"
when 2..5 then "chapter1.xhtml"
when 6..10 then "chapter2.xhtml"
when 11..18 then "chapter3.xhtml"
when 19..30 then "chapter4.xhtml"
else "chapter unknown"
end
#optionally: do something with title
end
答案 3 :(得分:4)
这是一种简单的方法,只返回第一个匹配键的值:
# setup
i = 17;
hash = { 1..10 => :a, 11..20 => :b, 21..30 => :c };
# find key
hash.find { |k, v| break v if k.cover? i }
答案 4 :(得分:1)
在此topic找到论坛。他们建议
class RangedHash
def initialize(hash)
@ranges = hash
end
def [](key)
@ranges.each do |range, value|
return value if range.include?(key)
end
nil
end
end
现在您可以像
一样使用它ranges = RangedHash.new(
1..10 => 'low',
21..30 => 'medium',
41..50 => 'high'
)
ranges[5] #=> "low"
ranges[15] #=> nil
ranges[25] #=> "medium"
答案 5 :(得分:1)
试试这个:
def find_chapter(page_number)
@chapters.select{ |chapters_key| chapters_key === page_number.to_i}.values.first
end
然后你就这样称呼它:
find_chapter(10)
=> "chapter2.xhtml"
find_chapter(40)
=> nil