使用 ruby 从 csv 文件中删除重复项
Removing duplicates from a csv file using ruby
我有一个包含以下数据的 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
任何人都可以帮助我理解逻辑!
为了便于说明,我在您的 table:
中添加了第四行
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"]]
如果您想添加回 header 行:
a.unshift(arr.first)
#=> [["Sno", "Scenario", "Result", "Description"],
# ["1", "Sce_1", "Pass", "Pass"],
# ["2", "Sce_2", "Pass", "Pass"],
# ["3", "Sec_3", "Fail", "Pass"]]
如果要排除所有 "Fail" 行,即使没有对应的 "Pass" 行(至于 Sno == "3"
),您可以这样做:
h.flat_map { |_,a| a.reject { |e| e[2]=="Fail" } }
#=> [["1", "Sce_1", "Pass", "Pass"],
# ["2", "Sce_2", "Pass", "Pass"]]
我有一个包含以下数据的 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
任何人都可以帮助我理解逻辑!
为了便于说明,我在您的 table:
中添加了第四行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"]]
如果您想添加回 header 行:
a.unshift(arr.first)
#=> [["Sno", "Scenario", "Result", "Description"],
# ["1", "Sce_1", "Pass", "Pass"],
# ["2", "Sce_2", "Pass", "Pass"],
# ["3", "Sec_3", "Fail", "Pass"]]
如果要排除所有 "Fail" 行,即使没有对应的 "Pass" 行(至于 Sno == "3"
),您可以这样做:
h.flat_map { |_,a| a.reject { |e| e[2]=="Fail" } }
#=> [["1", "Sce_1", "Pass", "Pass"],
# ["2", "Sce_2", "Pass", "Pass"]]