Determining if array elements are in a range

So, we've got this little problem, that we know how to solve but we think that there might be a better way of doing it, so here we go.

We have an array of number, let's say something like

[29, 34, 58, 91, 102, 107, 110, 136, 145, 154, 167, 226, 239, 240, 251, 261, 268, 271, 290, 305, 320, 350, 505, 521, 529, 533, 544, 583, 596, 598, 618, 620, 665, 687, 725, 779, 780, 795, 857, 858, 900, 1013, 1130, 1163, 1336, 1356, 1416, 1480, 1500, 1950, 2300, 3450, 3509, 4400, 5300, 7300, 7600, 14000]

We need to know if the numbers are in certain ranges, so for example, does the array contain at least one number in the following ranges

0 to 500 501 to 1000 1001 to 5000

now we think the solution is something like this (let's say the array of numbers is called values)

ranges = [[0,500],[501, 1000], [1001, 5000]] range_found = {:0 => false, :501 => false, :1001 => false} current_position = 0

for range in ranges

    while (values[current_position] < range[0] || values[current_position] > range[0]) && current_position < values.length         current_position = current_position + 1     end

    range_found[range[0].to_sym] = current_position < values.length

end

Anyone have any idea on how to make this simpler?

Dale

Hi --

So, we've got this little problem, that we know how to solve but we think that there might be a better way of doing it, so here we go.

We have an array of number, let's say something like

[29, 34, 58, 91, 102, 107, 110, 136, 145, 154, 167, 226, 239, 240, 251, 261, 268, 271, 290, 305, 320, 350, 505, 521, 529, 533, 544, 583, 596, 598, 618, 620, 665, 687, 725, 779, 780, 795, 857, 858, 900, 1013, 1130, 1163, 1336, 1356, 1416, 1480, 1500, 1950, 2300, 3450, 3509, 4400, 5300, 7300, 7600, 14000]

We need to know if the numbers are in certain ranges, so for example, does the array contain at least one number in the following ranges

0 to 500 501 to 1000 1001 to 5000

now we think the solution is something like this (let's say the array of numbers is called values)

ranges = [[0,500],[501, 1000], [1001, 5000]] range_found = {:0 => false, :501 => false, :1001 => false} current_position = 0

for range in ranges

   while (values[current_position] < range[0] || values[current_position] > range[0]) && current_position < values.length        current_position = current_position + 1    end

   range_found[range[0].to_sym] = current_position < values.length

end

Anyone have any idea on how to make this simpler?

The first thing to do is use the Range class, rather than reinventing it :slight_smile: So maybe something like this:

   ranges = [0..500, 501..1000, 1001..5000]    results = {}    values.each do |v|      results[v] = ranges.any? {|r| r.include?(v) }    end

You could also use inject to similar ends:

   results = values.inject({}) {|hash, v| ranges.any? {|r| r.include?(v) } }

I"m not sure why you're doing a #to_sym operation on the numbers. You can reintroduce it if you want. It seems easier just to use the numbers.

David