Ruby on Rails中按location_id合并数组对象的技术实现需求
问题描述
通过查询获取两组数组filled与empty,合并得到data数组后,生成的结果中存在相同location_id的对象。需要合并这些同location_id的对象,保留有效的location_name,并整合onhandcylynder和emptycylynder字段值,得到预期的JSON输出。
原生成数组代码
filled = Product.on_hand_location(pid).to_a empty = Product.on_hand_location_empty_cylinder(pid).to_a data = filled + empty result = data.map{ |k| { details: { location_id: k['location_id'], "location_name"=>k['location_name'], "onhandcylynder"=>k['onhand'] == nil ? 0 : k['onhand'], "emptycylynder"=> k['emptyonhand'] == nil ? 0 : k['emptyonhand'] } , } } respond_with [ onhand: result ]
当前输出JSON(需合并同location_id对象)
[{ "onhand": [{ "details": { "location_id": 1, "location_name": "Capitol Drive", "onhandcylynder": "4.0", "emptycylynder": 0 } }, { "details": { "location_id": 2, "location_name": "SM City Butuan", "onhandcylynder": "5.0", "emptycylynder": 0 } }, { "details": { "location_id": 1, "location_name": null, "onhandcylynder": 0, "emptycylynder": "2.0" } } ] }]
期望输出JSON
[{ "onhand": [{ "details": { "location_id": 1, "location_name": "Capitol Drive", "onhandcylynder": "4.0", "emptycylynder": 0 } }, { "details": { "location_id": 2, "location_name": "SM City Butuan", "onhandcylynder": "5.0", "emptycylynder": "2.0" } } ] }]
解决方案
修改代码,通过group_by按location_id分组,再合并每组内的字段值:
filled = Product.on_hand_location(pid).to_a empty = Product.on_hand_location_empty_cylinder(pid).to_a data = filled + empty # 按location_id分组,合并每组数据 grouped_data = data.group_by { |item| item['location_id'] }.values.map do |group| # 合并字段:保留有效location_name,累加数量字段 merged = group.reduce do |acc, item| { 'location_id' => acc['location_id'], 'location_name' => acc['location_name'] || item['location_name'], 'onhand' => (acc['onhand'] || 0).to_f + (item['onhand'] || 0).to_f, 'emptyonhand' => (acc['emptyonhand'] || 0).to_f + (item['emptyonhand'] || 0).to_f } end # 转换为目标输出格式 { details: { location_id: merged['location_id'], location_name: merged['location_name'], onhandcylynder: merged['onhand'].zero? ? 0 : merged['onhand'].to_s, emptycylynder: merged['emptyonhand'].zero? ? 0 : merged['emptyonhand'].to_s } } end respond_with [onhand: grouped_data]
关键修改说明
- 分组:使用
group_by { |item| item['location_id'] }将相同location_id的数据归为一组 - 合并字段:
location_name:优先保留已有非空值,若当前值为空则取后续项的非空值onhand和emptyonhand:转换为浮点数后累加,避免字符串拼接错误
- 格式转换:最后将合并后的数据转换为目标结构,处理数值为0时的显示逻辑
内容的提问来源于stack exchange,提问作者coolshox
相关产品推荐
相关产品推荐

