47 lines
1 KiB
Ruby
47 lines
1 KiB
Ruby
|
class String
|
||
|
def from_csv(sep = /,/)
|
||
|
ret = chomp.split(sep)
|
||
|
idx = 0;
|
||
|
while idx < ret.length do
|
||
|
if ret[idx][0] == "\""[0]
|
||
|
while ret[idx][-1] != "\""[0]
|
||
|
raise "Unterminated quote" if idx+1 >= ret.length
|
||
|
ret[idx] = ret[idx]+","+ret[idx+1]
|
||
|
ret.delete_at(idx+1)
|
||
|
end
|
||
|
ret[idx] = ret[idx].sub(/^"/, "").sub(/"$/, "")
|
||
|
end
|
||
|
idx += 1
|
||
|
end
|
||
|
ret
|
||
|
end
|
||
|
end
|
||
|
|
||
|
class Array
|
||
|
def from_csv
|
||
|
self.map { |l| l.to_s.chomp.from_csv }
|
||
|
end
|
||
|
|
||
|
def to_csv(f)
|
||
|
File.open(f, "w+") { |f| each { |row| f.puts(row.join(',')) }}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
class IO
|
||
|
def from_csv(args = {})
|
||
|
header = args.fetch(:header, false)
|
||
|
separator = args.fetch(:separator, /,/)
|
||
|
keys = readline.chomp.
|
||
|
sub(/ *$/, "").sub(/^ */,"").
|
||
|
from_csv(separator) if header;
|
||
|
map { |l| l.to_s.chomp.from_csv(separator) }.
|
||
|
map { |a| if header then keys.zip(a).to_h else a end }
|
||
|
end
|
||
|
end
|
||
|
|
||
|
class File
|
||
|
def File.csv(f, args = {})
|
||
|
File.open(f) {|io| io.from_csv(args) }
|
||
|
end
|
||
|
end
|