在 Rails 上查找 Ruby 中 2 列的匹配值

Find matching values of 2 columns in Ruby on Rails

我正在读取带有 RoR 的 CSV 文件并打印出 HTML table 但需要标记 2 个单独列的值何时与另一行匹配。

CSV 看起来像

name | value1 | value2| value3
bob  |    2   |   3   |   foo
jim  |    4   |   5   |   bar
tim  |    2   |   7   |   foo

我想查找 VALUE1 和 VALUE3 何时匹配此 CSV 文件中另一行的 VALUE1 和 VALUE3 的值(在本例中:“2”和 "foo" 匹配 bob 和 tim)

结果会是这样的:

name | value1 | value2| value3 | duplicate
bob  |    2   |   3   |   foo  |   Y
jim  |    4   |   5   |   bar  |   N
tim  |    2   |   7   |   foo  |   Y

我正在打印 table

<% file.each do |row| %>
<tr>
  <% row.each do |k, v| %>
    <td><% v %></td>
  <% end %>
</tr>
<% end %>

我想做的是在找到匹配列时标记 table 行。

想起XKCD的某部漫画,判断一张照片是不是在国家公园拍的, 如果照片是一只鸟... LOL

所以您需要更复杂的数据结构来比较每一行与之前的所有行。 好的,最终编辑: 我添加了代码以仅在这是一组值第一次重复时才设置新颜色,这样,如果它再次重复,它将获得相同的颜色。还添加了附加列的代码,显示哪些行也匹配。

<% output_file = [] %>  
<%  color_offset = 26214 %>

<%  file.each do |row| %>
  <%  row.unshift 0x00FFFF     # add last 4 digits of bgcolor as first item in each row   %>
  <%  row.push ''       #add a column at the end for row match numbers  
  <%  output_file.each_with_index do |prev_row,i| # look for current row values in previous entries  %>

    <%  if prev_row[2] == row[2] and prev_row[4] == row[4]  %>
          <% if prev_row[0] == 0x00FFFF %>
            <%  prev_row[0] -= color_offset  %>
            <%  row[0] = prev_row[0]   %>
          <% else %>
            <% row[0] = prev_row[0] %>
          <% end %>

          <%  color_offset -= 52     %>
          <%  row[-1] += "#{(i + 1)}, "  %>
    <%  end   %>       
   <%  end %>

  <%  output_file << row   # add the new row to the look-back array %>

<%  end  %>

<%  output_file.each do |output_row|  %>
     <tr bgcolor=#FF<% output_row[0].to_s(16).upcase %>  >
     <% output_row.shift %>
     <% output_row.each do |v|    # why the k? you don't use it here.  %>            
     <td> <% v %> </td>                
     <%  end   %> 
     </tr>
<%  end    %>

所以你拿每一行,循环遍历之前检查过的行数组,如果它匹配将它们的第一个项目更改为匹配的十六进制 4 位数字颜色(G 和 B,R 在末尾添加),然后将新行复制到先前检查的行数组中。

如果一行匹配不止一次,这会中断,因为它只会为新匹配​​项和前一个匹配项提供相同的颜色。但是我添加了最后一列,告诉您每个人之前匹配的行。因此,如果它突出显示,您可以跳回该行。

还有其他方法可以突出显示,也许可以向前复制新颜色,这样完全相同的行中有两个以上的颜色会相同。

上面答案的另一个版本,简单ruby而不是ERB,所以更容易测试

我想展示我的 ruby 小程序来展示我是如何做到这一点的。在 ERB 版本中阅读起来并不容易,可以将其复制并粘贴到 IRB 中或通过管道传输到文件中。

 puts '<head></head>'
 puts '<body>'
 puts '<table>'
 puts '<tr><th>#</th><th>col1</th><th>col2</th><th>col3</th><th>col4</th><th>Matching Previous Rows:</th></tr>'

file = [%w(Bob foo 32 3), %w(Joe zip 4 foo), %w(Joe baz 4 foo), %w(Steve foo 44 3), %w(Bob baz 32 foo), %w(Mary baz 4 wow), %w(Lisa 34 wow 2), %w(Art 45 foo E),%w(Bob foo 32 3)]
output_file = []

 file.each do |row|
 row.unshift 0x00FFFF  #make first value the background color of 0xFFFFFF
 row.push ''            #add a column for matches
 output_file.each_with_index do |prev_row,i|   # look for current row values in previous entries
      if prev_row[2] == row[2] and prev_row[4] == row[4]
        if prev_row[0] == 0x00FFFF
          prev_row[0] = rand(0xFFFF0)
          row[0] = prev_row[0]
        else
          row[0] = prev_row[0]
        end
        row[-1] += "#{(i + 1)}, "
      end
     end
 output_file << row               #add the new row to the look-back array

 end

 output_file.each_with_index do |output_row,i|
   print "<tr bgcolor=##{output_row[0].to_s(16).upcase}F  >"
   output_row.shift
   print "<td>#{i + 1}</td>"
  output_row.each do |v|           #why the k? you don't use it here.
     print '<td>' + "#{v}" + ' </td>'
  end
  puts '</tr>'
 end
 puts '</table>'
 puts '</body>'