在 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>'
我正在读取带有 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>'