使用ruby从csv文件中删除重复项

时间:2015-04-01 09:17:53

标签: ruby csv duplicates

我有一个包含以下数据的csv文件

Sno Scenario    Result  Description
1   Sce_1   Pass    Pass
2   Sce_2   Pass    Pass
1   Sce_1   Fail    Failed

在这种情况下,我有2个相同的序列号。我想只看到结果为Pass的行,并删除其余的重复行。

我尝试过以下但仍然无法得到它!

CSV.open('New.csv', 'w') do |csv|
   CSV.read('Merged_files.csv').uniq!{|x| x[1]}.each do |row|
       csv << row
   end
end

任何人都可以帮助我获得逻辑!

1 个答案:

答案 0 :(得分:1)

为了便于说明,我在表格中添加了第四行:

require 'csv'

arr = CSV.read("x.csv")
  #=> [["Sno", "Scenario", "Result", "Description"],
  #    ["1", "Sce_1", "Pass", "Pass"],
  #    ["2", "Sce_2", "Pass", "Pass"],
  #    ["1", "Sec_1", "Fail", "Pass"],
  #    ["3", "Sec_3", "Fail", "Pass"]]

您可以删除不需要的元素,如下所示:

arr[1..-1].group_by(&:first).map { |_,a|
  (a.size > 1) ? a.reject { |e| e[2]=="Fail" } : a }
  #=> [[["1", "Sce_1", "Pass", "Pass"]],
  #    [["2", "Sce_2", "Pass", "Pass"]],
  #    [["3", "Sec_3", "Fail", "Pass"]]]

步骤:

h = arr[1..-1].group_by(&:first)
  #=> {"1"=>[["1", "Sce_1", "Pass", "Pass"],
  #          ["1", "Sec_1", "Fail", "Pass"]],
  #    "2"=>[["2", "Sce_2", "Pass", "Pass"]],
  #    "3"=>[["3", "Sec_3", "Fail", "Pass"]]}

h.map { |_,a| (a.size > 1) ? a.reject { |e| e[2]=="Fail" } : a }
  #=> [[["1", "Sce_1", "Pass", "Pass"]],
  #    [["2", "Sce_2", "Pass", "Pass"]],
  #    [["3", "Sec_3", "Fail", "Pass"]]]

如果对于给定的Sno/Scenario,最多只有一个"Pass"行,则可以改为使用Enumerable#flat_map

a = h.flat_map { |_,a| (a.size > 1) ? a.reject { |e| e[2]=="Fail" } : a }
  #=> [["1", "Sce_1", "Pass", "Pass"],
  #    ["2", "Sce_2", "Pass", "Pass"],
  #    ["3", "Sec_3", "Fail", "Pass"]]

如果您想要添加标题行:

a.unshift(arr.first)
  #=> [["Sno", "Scenario", "Result", "Description"],
  #    ["1", "Sce_1", "Pass", "Pass"],
  #    ["2", "Sce_2", "Pass", "Pass"],
  #    ["3", "Sec_3", "Fail", "Pass"]]

如果要排除所有“失败”行,即使没有相应的“通过”行(对于Sno == "3"),也可以这样做:

h.flat_map { |_,a| a.reject { |e| e[2]=="Fail" } }
  #=> [["1", "Sce_1", "Pass", "Pass"],
  #    ["2", "Sce_2", "Pass", "Pass"]]