Ruby ERB嵌套循环如何避免同一食材元素被重复遍历
问题原因
你当前的循环嵌套顺序存在逻辑问题:把@fridge的遍历放在了食材遍历的外层,导致每一个食材都会被@fridge里的4个值逐一匹配,最终同一个食材会被重复渲染4次,且原逻辑在单次不匹配时就立刻渲染红叉,会导致同一个食材位置同时出现多个红/绿状态标识。
实现方案
调整循环嵌套层级,把单种食材的遍历放在外层,对每个食材设置匹配标记:只要在冰箱食材里匹配到对应内容,就立刻终止当前食材对剩余冰箱项的遍历,等匹配逻辑全部跑完后,再根据最终匹配结果渲染一次状态即可。
调整后的ERB代码如下:
<div> <% @ingredientsOfRecipes.each do |item| %> <ul> <%= item["name"] %> <% # 食材循环移至外层,保证每个食材只渲染一次 %> <% item['ingredients'].each do |ingredient| %> <li style="display: flex; flex-direction: row; align-items: center"> <% matched = false # 初始化当前食材的匹配标记 %> <% @fridge.each do |f| %> <% if ingredient.include? f.content %> <% matched = true %> <% break # 匹配成功立刻跳出冰箱项循环,不再做后续重复判断 %> <% end %> <% end %> <% if matched %> <p style="color: green"> <%= ingredient %> <i class="fa-solid fa-check" style="color: green; margin-left: 10px"></i> </p> <% else %> <p style="color: red"> <%= ingredient %> <i class="fa-solid fa-xmark" style="color: red; margin-left: 10px"></i> </p> <% end %> </li> <% end %> </ul> <% end %> </div>
调整说明
- 修正了原代码里的CSS笔误:
flex-drirection改为正确的flex-direction - 调整循环嵌套顺序后,每个食材只会对应一个列表项,不会因为
@fridge存储了4个值就重复输出4次 - 移除了原逻辑里冗余的
elsif ingredient.exclude? f.content判断:遍历完所有冰箱项都没匹配到,自然就是不存在的状态,不需要每次不匹配就立刻渲染红叉 - 匹配成功后通过
break终止当前食材的剩余冰箱遍历逻辑,完全避免重复判断
内容的提问来源于stack exchange,提问作者Théo
相关产品推荐
相关产品推荐

