我正在寻找一种方法,它会将数组中最接近的5个数字返回给我。这是我要让我开始的。我想比较差异,但我觉得必须有一个更简单的方法。
def get_suggested_items
@suggested_items = []
new_price = self.price
products = Product.all
products.each do |product, difference|
price = product.price
old_difference = new_price - product.price
difference = (new_price - product.price).abs
while difference < old_difference
@suggested_items << product
end
end
我希望以最优惠的价格将@suggested_items阵列退回
答案 0 :(得分:4)
SQL就是为这类东西而设计的。将以下类方法添加到Product
模型中:
class Product < ActiveRecord::Base
def self.with_price_nearest_to(price)
order("abs(products.price - #{price})")
end
end
然后你可以写:
Product.with_price_nearest_to(3.99).limit(5)
与您在问题中概述的内容相比,此方法具有明显的性能优势。在这种情况下,数据库会为您进行计算和排序,并仅返回ActiveRecord所需的5个产品。当您执行Product.all
甚至Product.each
时,您强制ActiveRecord为表中的每一行实例化一个模型,随着表变大,这会变得很昂贵。
请注意,此方法仍需要全表扫描;如果您想进一步提高性能,可以在price
表上的products
列添加索引。
答案 1 :(得分:1)
假设arr
是整数的排序数组。 (如果它没有排序,那么排序为第一步。)
我假设你想从数组a = arr[i,5]
中找到五个元素的序列,这样a.last-a.first
对于所有i
,0 <= i <= arr.size-4
来说都是最小的。如果这是正确的,那么它只是:
start_index = (arr.size-4).times.min_by { |i| arr[i+4]-arr[i] }
假设
arr = [1, 2, 4, 5, 8, 9, 11, 12, 13, 15, 17, 19, 23, 24, 24, 25, 30]
start_index = (arr.size-4).times.min_by { |i| arr[i+4]-arr[i] }
#=> 4
所以&#34;最接近&#34;五个数字将是:
arr[4,5]
#=> [8, 9, 11, 12, 13]