带'if'语句的嵌套循环

时间:2018-10-03 23:16:37

标签: ruby-on-rails ruby loops if-statement nested-loops

我试图遍历选项数组,并检查每个选项以查看其是否与不同数组中的其他选项匹配。如果两个选项匹配,则执行一件事;如果两个选项不匹配,则执行另一件事。

我有3 ^ 2个可用选项,它可以运行9次。 import { AsYouTypeFormatter } from 'google-libphonenumber'; const appDiv: HTMLElement = document.getElementById('app'); appDiv.innerHTML = ` <h1>Libphonenumber Playground</h1> <input id="input" type="text"> `; this.formatter = new AsYouTypeFormatter('us'); const input = document.getElementById('input') as HTMLInputElement; input.addEventListener('keyup', (event: KeyboardEvent) => { console.log(this.formatter.inputDigit(event.key)); }); (true, false, false)(false, true, false)都不理想。相反,我希望看到类似以下内容的东西:(false, false, true)(true)(false)

它位于erb文件中的前端。我意识到那里不应该有逻辑,并且很乐意重构建议,但是在我弄清楚如何使循环正常工作之后就计划将其删除。

前端代码:

(true)

相关控制器代码<% @available_sites.each do |available_site| %> <% @sites.each do |site| %> <% if site.review_site == available_site.name %> <div class="site-row columns"> <div class="column col-4 col-md-10 col-mx-auto"> <div class="site-tile"> <a href="<%= site.direct_review_url %>" style="background-image: url(<%= image_path("review_site_logos/#{site.review_site}.png")%>); background-size: cover;"></a> </div> </div> <div class="column col-4 col-md-10 col-mx-auto"> <span>Average Rating: <%= site.average_rating %></span> <span>Review Site: <a href="<%= site.direct_review_url %>"><%= site.review_site %></a></span> </div> <div class="column col-4 col-md-10 col-mx-auto is-flex-centered request-row-buttons"> <%= link_to 'Show', [site.location, site] %> <%= link_to 'Edit', [:edit, site.location, site] %> <%= link_to 'Destroy', [site.location, site], method: :delete, data: { confirm: 'Are you sure?' } %> </div> </div> <% elsif site.review_site != available_site.name %> <div class="site-row columns"> <div class="column col-4 col-md-10 col-mx-auto"> <div class="site-tile"> <a href="<%= available_site.link_to_info %>" style="background-image: url(<%= image_path("review_site_logos/#{available_site.name}.png")%>); background-size: cover;"></a> </div> </div> <div class="column col-4 col-md-10 col-mx-auto"> <span>Sign Up for <%= available_site.name %> Business Page: <%= available_site.link_to_signup %></span> <span>Review Site: <a href="<%= site.direct_review_url %>"><%= site.review_site %></a></span> </div> <div class="column col-4 col-md-10 col-mx-auto is-flex-centered"> <%= link_to "Add #{available_site.name} to Review App", new_location_site_path(review_site: "#{available_site.name}"), class: 'btn btn-primary' %> </div> </div> <% end %> <% end %> <% end %> -policy_scope用于授权:

sites_controller.rb

事件模式代码

def index
    @sites = policy_scope(@location.sites)
    @available_sites = AvailableSite.all
  end

我正在寻找帮助/有关处理嵌套循环的新方向。

2 个答案:

答案 0 :(得分:1)

为了确保我们在同一页面上,我将重申您的问题:

您有AvailableSite的列表,并且要根据是否有可见的Site来显示不同的信息。

如果准确的话,您将要使用find。像这样:

<% @available_sites.each do |available_site| %>
  <% site = @sites.find { |s| s.review_site == available_site.name } %>

  <% if site.present? %>
    <%# view fragment when you have a site %>
  <% else %>
    <%# view fragment when you don't have a site %>
  <% end %>
<% end %>

每个AvailableSite仅输出一组元素。

答案 1 :(得分:1)

首先,让我们将两个视图部分移到实际的部分文件中,以使其更易于解析和维护。这样我们就可以

<% @available_sites.each do |available_site| %>
  <% @sites.each do |site| %>
    <% if site.review_site == available_site.name %>
       <% render partial: "sites/site_available", locals: {site: site}>
    <% else %>
       <% render partial: "sites/site_unavailable", locals: {site: site}>
    <% end %>
  <% end %>
<% end %>

好玩得多!

接下来,我们不需要在嵌套循环中进行渲染;这就是为什么您获得9个渲染而不是3个渲染的原因。您需要在@sites上进行一个外部循环。在每个循环中,它将(1)检查可用性,(2)渲染。看起来更像

<% @sites.each do |site| %>
  <% if site_available?(@site, @available_sites) %>
     <% render partial: "sites/site_available", locals: {site: site}>
  <% else %>
     <% render partial: "sites/site_unavailable", locals: {site: site}>
  <% end %>
<% end %>

您有很多选择来代替site_available?实际做什么,包括:

  1. 将其定义为辅助方法,查看代码与上面完全相同。不是我推荐的方法,但可以完成工作。
  2. 使用@available_sites.map(&:name).include?(@site.name)。现在,很明显,这是一个循环(include?将循环),但是渲染发生在该循环之外。效率低下,但是AvailableSite.all也是如此,所以暂时可以::)
  3. 使用演示者:这只是一个简单的Ruby类,它将以site作为initialize方法的参数,并且具有其他逻辑和属性(例如@available)您可以添加而不污染模型,视图或控制器。如果事情变得更复杂,我总是主张从这里开始,但是现在可能有点笨拙。

class AvailableSitePresenter
  def new(site, available_sites)
    @site = site
    @available = available_sites.map(&:name).include?(@site.name)
  end

  def available?
    @available
  end
end