Reputation: 5897
Let's say I have a min
and a max
number. max
can be anything, but min
will always be greater than zero.
I can get the range min..max
and let's say I have a third number, count
-- I want to divide the range by 10 (or some other number) to get a new scale. So, if the range is 1000
, it would increment in values of 100, 200, 300, and find out where the count lies within the range, based on my new scale. So, if count
is 235, it would return 2
because that's where it lies on the range scale.
Am I making any sense? I'm trying to create a heat map based on a range of values, basically ... so I need to create the scale based on the range and find out where the value I'm testing lies on that new scale.
I was working with something like this, but it didn't do it:
def heat_map(project, word_count, division)
unless word_count == 0
max = project.words.maximum('quantity')
min = project.words.minimum('quantity')
range = min..max
total = range.count
break_point = total / division
heat_index = total.to_f / word_count.to_f
heat_index.round
else
"freezing"
end
end
I figured there's probably an easier ruby way I'm missing.
Upvotes: 1
Views: 480
Reputation: 5467
Why not just use arithmetic and rounding? Assuming that number
is between min
and max
and you want the range split into n_div
divisions and x
is the number you want to find the index of (according to above it looks like min = 0
, max
= 1000, n_div = 10
, and x = 235
):
def heat_index(x, min, max, n_div)
break_point = (max - min).to_f/n_div.to_f
heat_index = (((x - min).to_f)/break_point).to_i
end
Then heat_index(235, 0, 1000, 10)
gives 2.
Upvotes: 4
Reputation: 6011
How's this? It makes an array of range boundaries and then checks if the number lies between them.
def find_range(min, max, query, increment)
values = []
(min..max).step(increment) { |value| values << value }
values.each_with_index do |value, index|
break if values[index + 1].nil?
if query > value && query < values[index + 1]
return index
end
end
end
EDIT: removed redundant variable
Upvotes: 1
Reputation: 66837
I'm just quickly brainstorming an idea, but would something like this help?
>> (1..100).each_slice(10).to_a.index { |subrange| subrange.include? 34 }
=> 3
>> (1..100).each_slice(5).to_a.index { |subrange| subrange.include? 34 }
=> 6
This tells you in which subrange (the subrange size is determined by the argument to each_slice
) the value (the argument to subrange.include?
) lies.
>> (1..1000).each_slice(100).to_a.index { |subrange| subrange.include? 235 }
=> 2
Note that the indices for the subranges start from 0, so you may want to add 1 to them depending on what you need. Also this isn't ready as is, but should be easy to wrap up in a method.
Upvotes: 4