使用数字范围选择数组项

时间:2012-11-25 03:50:51

标签: ruby arrays hash range

我有四种尺寸,每种尺寸均以平方英尺为准:

# The sizes. Sizes are in sq ft (min, max)
size_hash = {
  'Large'  => [70,139],
  'Medium' => [15,69],
  'Small'  => [1,14]
}

如果我给出了号码40,我如何从数组中返回Medium作为大小?

我需要做这样的事情吗?:

# The sizes. Sizes are in sq ft (min, max)
size_hash = {
  [70..139]  => 'Large',
  #... etc
}

4 个答案:

答案 0 :(得分:5)

您可以使用 proc

size_store = proc{ |n|
  case n
  when 70..139
    'Large'
  when 15..69
    'Medium'
  when 1..14
    'Small'
  end
}
# USAGE: size_store[40]

答案 1 :(得分:4)

size_hash.find{|_, (min, max)| (min..max) === 40}[0]
# => "Medium"

但我认为最好先存储范围而不是最小值和最大值。

size_hash = {
    'Large'  => 70..139,
    'Medium' => 15..69,
    'Small'  => 1..14,
}

size_hash.find{|_, r| r === 40}[0]
# => "Medium"

答案 2 :(得分:2)

另一个解决边缘案件的解决方案......

@size_hash = {
  'Large'  => 70..139,
  'Medium' => 15..69,
  'Small'  => 1..14,
}

some_value = @size_hash["Small"]
@min = some_value.first
@max = some_value.last
@size_hash.each_pair do |k, v|
    @min = [@min, v.first].min
    @max = [@max, v.last].max
end

puts "size_hash goes from #{@min} to #{@max}"

    # Given a number, return the name of the range which it belongs to.
def whichSize(p_number)
    @size_hash.each_pair do |k, v|
        return k if v.include?(p_number)
    end

    return "below minimum" if p_number < @min
    "above maximum" if p_number > @max
end

# test
[-10, 0, 1, 10, 14, 15, 20, 69, 70, 80, 139, 140, 1000].each do |e|
    puts "size of #{sprintf("%4s", e)} is #{whichSize(e)}"
end

$ ruby -w t.rb 
size_hash goes from 1 to 139
size of  -10 is below minimum
size of    0 is below minimum
size of    1 is Small
size of   10 is Small
size of   14 is Small
size of   15 is Medium
size of   20 is Medium
size of   69 is Medium
size of   70 is Large
size of   80 is Large
size of  139 is Large
size of  140 is above maximum
size of 1000 is above maximum

答案 3 :(得分:1)

如果您将范围存储为键,则可以执行以下操作:

size_hash = Hash.new {|hash, key| hash.find {|range,_| range.cover?(key) }.last }.merge({
  (1..14)   => 'Small',
  (15..69)  => 'Medium',
  (70..139) => 'Large'
})

这会在哈希中设置默认proc,因此当您查找值size_hash[9]时,会返回覆盖该值的第一个范围。请记住,这不会处理超出范围的错误。