循环中求和并保留最大值:多商品运输尺寸计算实现疑问
解决商品运输尺寸计算的最优方案
我来帮你搞定这个问题!你的核心需求是遍历商品列表,找出最大的长度和宽度,同时累加所有商品的高度,原代码的问题在于每次循环都直接覆盖了临时变量的值,没法保留历史的最大值和累加结果。下面给你两种实现思路,其中第二种更符合Ruby的简洁风格,也更高效。
方法一:循环内逐步更新(直观易懂)
先初始化最大值和总和变量,然后在每次循环里更新它们:
# 初始化变量:最大长度、最大宽度从0开始,总高度初始为0 max_length = 0 max_width = 0 total_height = 0 params[:rate][:items].each do |item| product_id = item[:product_id] product = Product.find_by(product_id: product_id) # 用find_by更简洁,找不到返回nil next unless product # 避免商品不存在时抛出错误 # 更新最大长度:取当前最大值和商品长度的较大值 max_length = [max_length, product.length].max # 更新最大宽度:同理 max_width = [max_width, product.width].max # 累加高度 total_height += product.height end # 最后得到的三个变量就是你要的结果 puts "最大长度:#{max_length}" puts "最大宽度:#{max_width}" puts "总高度:#{total_height}"
方法二:Ruby Enumerable 优雅实现(更简洁高效)
利用Ruby的集合方法,先把所有商品的尺寸数据收集起来,再一次性计算最大值和总和,同时还能避免N+1数据库查询(原代码每次循环查一次数据库,性能较差):
# 1. 先收集所有商品ID,批量查询数据库,避免多次查询 product_ids = params[:rate][:items].map { |item| item[:product_id] } products = Product.where(product_id: product_ids) # 2. 计算最大长度、最大宽度、总高度 max_length = products.max_by(&:length)&.length || 0 max_width = products.max_by(&:width)&.width || 0 total_height = products.sum(&:height) # 输出结果 puts "最大长度:#{max_length}" puts "最大宽度:#{max_width}" puts "总高度:#{total_height}"
关键细节说明:
max_by(&:length):会返回数组中length属性最大的商品对象,后面加&.length是为了处理没有商品的情况(避免nil报错),最后用|| 0保证结果是数字类型。sum(&:height):直接对集合中每个商品的height属性求和,这就是你提到的sum(&:symbol)的用法,非常简洁高效。- 批量查询:先收集所有ID再一次性查询,比循环里逐个查询效率高很多,尤其是商品数量较多的时候。
内容的提问来源于stack exchange,提问作者rlsaj
相关产品推荐
相关产品推荐

