我有两个带有一些常用标题的CSV文件,其他只出现在一个或另一个中的文件,例如:
# csv_1.csv
H1,H2,H3
V11,V22,V33
V14,V25,V35
Run Code Online (Sandbox Code Playgroud)
# csv_2.csv
H1,H4
V1a,V4b
V1c,V4d
Run Code Online (Sandbox Code Playgroud)
我想合并两者并获得一个新的CSV文件,该文件结合了以前CSV文件的所有信息.在需要时注入新列,并使用空值提供新单元格.
结果示例:
H1,H2,H3,H4
V11,V22,V33,
V14,V25,V35,
V1a,,,V4b
V1c,,,V4d
Run Code Online (Sandbox Code Playgroud)
已接受的挑战 :)
#!/usr/bin/env ruby
require "csv"
module MergeCsv
class << self
def run(csv_paths)
csv_files = csv_paths.map { |p| CSV.read(p, headers: true) }
merge(csv_files)
end
private
def merge(csv_files)
headers = csv_files.flat_map(&:headers).uniq.sort
hash_array = csv_files.flat_map(&method(:csv_to_hash_array))
CSV.generate do |merged_csv|
merged_csv << headers
hash_array.each do |row|
merged_csv << row.values_at(*headers)
end
end
end
# Probably not the most performant way, but easy
def csv_to_hash_array(csv)
csv.to_a[1..-1].map { |row| csv.headers.zip(row).to_h }
end
end
end
if(ARGV.length == 0)
puts "Use: ruby merge_csv.rb <file_path_csv_1> <file_path_csv_2>"
exit 1
end
puts MergeCsv.run(ARGV)
Run Code Online (Sandbox Code Playgroud)