Given this example array of numbers:
sizes = [35, 40, 45, 50, 55, 60]
And this required size to fit:
fit_this = 30
I want to find the minimum size based on these given blocks:
sizes.min_by { |size| (size - fit_this).abs } #=> 35
sizes.min_by { |size| (size - fit_this*2).abs } #=> 60
The sizes are widths, and I'm trying to put as many fit_this
items into the width with the least amount of wasted space, so the fit_this
number can be doubled up if it's a better fit.
Is it possible to do this with min_by
? If not, what's the best way to do it in Ruby?
Let's examine the intermediate arrays by replacing min_by
with map
:
sizes.map { |size| (size - fit_this).abs }
#=> [5, 10, 15, 20, 25, 30]
sizes.map { |size| (size - fit_this*2).abs }
#=> [25, 20, 15, 10, 5, 0]
We can combine both calculations by returning element-wise arrays:
sizes.map { |size| [(size - fit_this).abs, (size - fit_this*2).abs] }
#=> [[5, 25], [10, 20], [15, 15], [20, 10], [25, 5], [30, 0]]
And use min
to fetch the smaller number of each pair:
sizes.map { |size| [(size - fit_this).abs, (size - fit_this*2).abs].min }
#=> [5, 10, 15, 10, 5, 0]
Applied to min_by
:
sizes.min_by { |size| [(size - fit_this).abs, (size - fit_this*2).abs].min }
#=> 60
Yes, we can do that.
The basic idea is we want to try for two cases for all sizes and choose what is the best fit:
sizes.min_by { |size| [(size - fit_this).abs, (size - fit_this * 2).abs].min }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.