tb 0.9 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +13 -11
- data/lib/tb.rb +14 -6
- data/lib/tb/catreader.rb +2 -2
- data/lib/tb/cmd_consecutive.rb +6 -2
- data/lib/tb/cmd_crop.rb +22 -3
- data/lib/tb/cmd_cross.rb +24 -0
- data/lib/tb/cmd_cut.rb +20 -10
- data/lib/tb/cmd_git.rb +20 -7
- data/lib/tb/cmd_group.rb +32 -0
- data/lib/tb/cmd_gsub.rb +21 -0
- data/lib/tb/cmd_join.rb +28 -0
- data/lib/tb/cmd_ls.rb +9 -0
- data/lib/tb/cmd_melt.rb +15 -0
- data/lib/tb/cmd_mheader.rb +15 -0
- data/lib/tb/cmd_nest.rb +27 -6
- data/lib/tb/cmd_newfield.rb +19 -2
- data/lib/tb/cmd_rename.rb +20 -0
- data/lib/tb/{cmd_grep.rb → cmd_search.rb} +37 -23
- data/lib/tb/cmd_shape.rb +69 -25
- data/lib/tb/cmd_sort.rb +20 -0
- data/lib/tb/cmd_tar.rb +38 -0
- data/lib/tb/cmd_to_json.rb +2 -2
- data/lib/tb/cmd_to_ltsv.rb +3 -3
- data/lib/tb/cmd_to_pnm.rb +3 -3
- data/lib/tb/cmd_to_tsv.rb +3 -3
- data/lib/tb/cmd_to_yaml.rb +3 -3
- data/lib/tb/cmd_unmelt.rb +15 -0
- data/lib/tb/cmd_unnest.rb +31 -7
- data/lib/tb/cmdmain.rb +2 -0
- data/lib/tb/cmdtop.rb +1 -1
- data/lib/tb/cmdutil.rb +9 -62
- data/lib/tb/csv.rb +21 -79
- data/lib/tb/enumerable.rb +42 -68
- data/lib/tb/enumerator.rb +15 -7
- data/lib/tb/{fieldset.rb → hashreader.rb} +37 -56
- data/lib/tb/hashwriter.rb +54 -0
- data/lib/tb/headerreader.rb +108 -0
- data/lib/tb/headerwriter.rb +116 -0
- data/lib/tb/json.rb +17 -15
- data/lib/tb/ltsv.rb +35 -96
- data/lib/tb/ndjson.rb +63 -0
- data/lib/tb/numericreader.rb +66 -0
- data/lib/tb/numericwriter.rb +61 -0
- data/lib/tb/pnm.rb +206 -200
- data/lib/tb/ropen.rb +54 -59
- data/lib/tb/tsv.rb +39 -71
- data/sample/excel2csv +24 -25
- data/sample/poi-xls2csv.rb +13 -14
- data/tb.gemspec +154 -0
- data/test/test_cmd_cat.rb +28 -6
- data/test/test_cmd_consecutive.rb +8 -3
- data/test/test_cmd_cut.rb +14 -4
- data/test/test_cmd_git_log.rb +50 -50
- data/test/test_cmd_grep.rb +6 -6
- data/test/test_cmd_gsub.rb +7 -2
- data/test/test_cmd_ls.rb +70 -62
- data/test/test_cmd_shape.rb +43 -6
- data/test/test_cmd_svn_log.rb +26 -27
- data/test/test_cmd_to_csv.rb +10 -5
- data/test/test_cmd_to_json.rb +16 -0
- data/test/test_cmd_to_ltsv.rb +2 -2
- data/test/test_cmd_to_pp.rb +7 -2
- data/test/test_csv.rb +74 -62
- data/test/test_ex_enumerable.rb +0 -1
- data/test/test_fileenumerator.rb +3 -3
- data/test/test_headercsv.rb +43 -0
- data/test/test_json.rb +2 -2
- data/test/test_ltsv.rb +22 -17
- data/test/test_ndjson.rb +62 -0
- data/test/test_numericcsv.rb +36 -0
- data/test/test_pnm.rb +69 -70
- data/test/test_reader.rb +27 -124
- data/test/test_tbenum.rb +18 -18
- data/test/test_tsv.rb +21 -32
- data/test/util_tbtest.rb +12 -0
- metadata +41 -19
- data/lib/tb/basic.rb +0 -1070
- data/lib/tb/reader.rb +0 -106
- data/lib/tb/record.rb +0 -158
- data/test/test_basic.rb +0 -403
- data/test/test_fieldset.rb +0 -42
- data/test/test_record.rb +0 -61
data/lib/tb/cmd_to_pnm.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
1
|
+
# Copyright (C) 2011-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -40,9 +40,9 @@ def (Tb::Cmd).main_to_pnm(argv)
|
|
40
40
|
op_to_pnm.parse!(argv)
|
41
41
|
exit_if_help('to-pnm')
|
42
42
|
argv = ['-'] if argv.empty?
|
43
|
-
|
43
|
+
reader = Tb::CatReader.open(argv, Tb::Cmd.opt_N)
|
44
44
|
with_output {|out|
|
45
|
-
|
45
|
+
reader.write_to_pnm(out)
|
46
46
|
}
|
47
47
|
end
|
48
48
|
|
data/lib/tb/cmd_to_tsv.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
1
|
+
# Copyright (C) 2011-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -40,9 +40,9 @@ def (Tb::Cmd).main_to_tsv(argv)
|
|
40
40
|
op_to_tsv.parse!(argv)
|
41
41
|
exit_if_help('to-tsv')
|
42
42
|
argv = ['-'] if argv.empty?
|
43
|
-
|
43
|
+
reader = Tb::CatReader.open(argv, Tb::Cmd.opt_N)
|
44
44
|
with_output {|out|
|
45
|
-
|
45
|
+
reader.write_to_tsv(out, !Tb::Cmd.opt_N)
|
46
46
|
}
|
47
47
|
end
|
48
48
|
|
data/lib/tb/cmd_to_yaml.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
1
|
+
# Copyright (C) 2011-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -41,8 +41,8 @@ def (Tb::Cmd).main_to_yaml(argv)
|
|
41
41
|
op_to_yaml.parse!(argv)
|
42
42
|
exit_if_help('to-yaml')
|
43
43
|
argv = ['-'] if argv.empty?
|
44
|
-
|
45
|
-
ary =
|
44
|
+
reader = Tb::CatReader.open(argv, Tb::Cmd.opt_N)
|
45
|
+
ary = reader.to_a
|
46
46
|
with_output {|out|
|
47
47
|
YAML.dump(ary, out)
|
48
48
|
out.puts
|
data/lib/tb/cmd_unmelt.rb
CHANGED
@@ -58,6 +58,21 @@ def (Tb::Cmd).op_unmelt
|
|
58
58
|
op
|
59
59
|
end
|
60
60
|
|
61
|
+
Tb::Cmd.def_vhelp('unmelt', <<'End')
|
62
|
+
Example:
|
63
|
+
|
64
|
+
% cat tst.csv
|
65
|
+
foo,variable,value
|
66
|
+
A,bar,1
|
67
|
+
A,baz,x
|
68
|
+
B,bar,2
|
69
|
+
B,baz,y
|
70
|
+
% tb unmelt tst.csv
|
71
|
+
foo,bar,baz
|
72
|
+
A,1,x
|
73
|
+
B,2,y
|
74
|
+
End
|
75
|
+
|
61
76
|
def (Tb::Cmd).main_unmelt(argv)
|
62
77
|
op_unmelt.parse!(argv)
|
63
78
|
exit_if_help('unmelt')
|
data/lib/tb/cmd_unnest.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
1
|
+
# Copyright (C) 2011-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -41,6 +41,27 @@ def (Tb::Cmd).op_unnest
|
|
41
41
|
op
|
42
42
|
end
|
43
43
|
|
44
|
+
Tb::Cmd.def_vhelp('unnest', <<'End')
|
45
|
+
Example:
|
46
|
+
|
47
|
+
% cat tst.csv
|
48
|
+
author,item
|
49
|
+
A,"name,length
|
50
|
+
foo,3
|
51
|
+
bar,5
|
52
|
+
"
|
53
|
+
B,"name,length
|
54
|
+
baz,2
|
55
|
+
qux,8
|
56
|
+
"
|
57
|
+
% tb unnest item tst.csv
|
58
|
+
author,name,length
|
59
|
+
A,foo,3
|
60
|
+
A,bar,5
|
61
|
+
B,baz,2
|
62
|
+
B,qux,8
|
63
|
+
End
|
64
|
+
|
44
65
|
def (Tb::Cmd).main_unnest(argv)
|
45
66
|
op_unnest.parse!(argv)
|
46
67
|
exit_if_help('unnest')
|
@@ -64,13 +85,16 @@ def (Tb::Cmd).main_unnest(argv)
|
|
64
85
|
elsif v.nil?
|
65
86
|
pairs2[f] = v
|
66
87
|
else
|
67
|
-
|
68
|
-
|
88
|
+
aa = CSV.parse(v)
|
89
|
+
reader = Tb::HeaderReader.new(lambda { aa.shift })
|
90
|
+
nested_tbl_rows = reader.to_a
|
91
|
+
nested_tbl_header = reader.get_named_header
|
92
|
+
nested_tbl_header.each {|f2|
|
69
93
|
unless nested_fields.has_key? f2
|
70
94
|
nested_fields[f2] = nested_fields.size
|
71
95
|
end
|
72
96
|
}
|
73
|
-
pairs2[f] =
|
97
|
+
pairs2[f] = [nested_tbl_header, nested_tbl_rows]
|
74
98
|
end
|
75
99
|
}
|
76
100
|
y2.yield pairs2
|
@@ -93,13 +117,13 @@ def (Tb::Cmd).main_unnest(argv)
|
|
93
117
|
}.each {|pairs|
|
94
118
|
pairs2 = {}
|
95
119
|
pairs.each {|f, v| pairs2[f] = v if f != target_field }
|
96
|
-
|
97
|
-
if
|
120
|
+
ntbl_header, ntbl_rows = pairs[target_field]
|
121
|
+
if ntbl_header.nil? || ntbl_rows.empty?
|
98
122
|
if Tb::Cmd.opt_unnest_outer
|
99
123
|
y.yield pairs2
|
100
124
|
end
|
101
125
|
else
|
102
|
-
|
126
|
+
ntbl_rows.each {|npairs|
|
103
127
|
pairs3 = pairs2.dup
|
104
128
|
npairs.each {|nf, nv|
|
105
129
|
if Tb::Cmd.opt_unnest_prefix
|
data/lib/tb/cmdmain.rb
CHANGED
data/lib/tb/cmdtop.rb
CHANGED
data/lib/tb/cmdutil.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
1
|
+
# Copyright (C) 2011-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -131,39 +131,11 @@ def split_field_list_argument(arg)
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def split_csv_argument(arg)
|
134
|
-
|
135
|
-
return []
|
134
|
+
return CSV.new(arg).shift || []
|
136
135
|
end
|
137
136
|
|
138
137
|
def tablereader_open(filename, &b)
|
139
|
-
Tb.open_reader(filename,
|
140
|
-
end
|
141
|
-
|
142
|
-
def tbl_generate_tsv(tbl, out)
|
143
|
-
if Tb::Cmd.opt_N
|
144
|
-
header = tbl.list_fields
|
145
|
-
Tb.tsv_stream_output(out) {|gen|
|
146
|
-
tbl.each {|rec|
|
147
|
-
gen << rec.values_at(*header)
|
148
|
-
}
|
149
|
-
}
|
150
|
-
else
|
151
|
-
tbl.generate_tsv(out)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def tbl_generate_ltsv(tbl, out)
|
156
|
-
if Tb::Cmd.opt_N
|
157
|
-
header = tbl.list_fields
|
158
|
-
Tb.ltsv_stream_output(out) {|gen|
|
159
|
-
tbl.each {|rec|
|
160
|
-
assoc = header.map {|f| [f, rec[f]] }
|
161
|
-
gen << assoc
|
162
|
-
}
|
163
|
-
}
|
164
|
-
else
|
165
|
-
tbl.generate_ltsv(out)
|
166
|
-
end
|
138
|
+
Tb.open_reader(filename, Tb::Cmd.opt_N, &b)
|
167
139
|
end
|
168
140
|
|
169
141
|
def with_output(filename=Tb::Cmd.opt_output)
|
@@ -191,37 +163,12 @@ def with_output(filename=Tb::Cmd.opt_output)
|
|
191
163
|
end
|
192
164
|
|
193
165
|
def output_tbenum(te)
|
194
|
-
filename = Tb::Cmd.opt_output
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
else
|
199
|
-
fmt = nil
|
200
|
-
end
|
201
|
-
if !fmt
|
202
|
-
case filename
|
203
|
-
when /\.csv\z/
|
204
|
-
fmt = 'csv'
|
205
|
-
when /\.ltsv\z/
|
206
|
-
fmt = 'ltsv'
|
207
|
-
when /\.json\z/
|
208
|
-
fmt = 'json'
|
209
|
-
end
|
210
|
-
end
|
211
|
-
if fmt
|
212
|
-
case fmt
|
213
|
-
when 'csv'
|
214
|
-
write_proc = lambda {|out| te.write_to_csv(out, !Tb::Cmd.opt_N) }
|
215
|
-
when 'ltsv'
|
216
|
-
write_proc = lambda {|out| te.write_to_ltsv(out) }
|
217
|
-
when 'json'
|
218
|
-
write_proc = lambda {|out| te.write_to_json(out) }
|
219
|
-
else
|
220
|
-
err("unexpected format: #{fmt.inspect}")
|
221
|
-
end
|
222
|
-
end
|
223
|
-
write_proc ||= lambda {|out| te.write_to_csv(out, !Tb::Cmd.opt_N) }
|
166
|
+
filename = Tb::Cmd.opt_output || '-'
|
167
|
+
numeric = Tb::Cmd.opt_N
|
168
|
+
filename, fmt = Tb.undecorate_filename(filename, numeric)
|
169
|
+
factory = Tb::FormatHash.fetch(fmt)[:writer]
|
224
170
|
with_output(filename) {|out|
|
225
|
-
|
171
|
+
writer = factory.new(out)
|
172
|
+
te.write_with(writer)
|
226
173
|
}
|
227
174
|
end
|
data/lib/tb/csv.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# lib/tb/csv.rb - CSV related fetures for table library
|
2
2
|
#
|
3
|
-
# Copyright (C) 2010-
|
3
|
+
# Copyright (C) 2010-2014 Tanaka Akira <akr@fsij.org>
|
4
4
|
#
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
6
6
|
# modification, are permitted provided that the following conditions
|
@@ -30,95 +30,37 @@
|
|
30
30
|
|
31
31
|
require 'csv'
|
32
32
|
|
33
|
-
|
34
|
-
def Tb.
|
35
|
-
|
33
|
+
module Tb
|
34
|
+
def Tb.csv_encode_row(ary)
|
35
|
+
ary.to_csv
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
43
|
-
aa = yield aa if block_given?
|
44
|
-
if header_fields.empty?
|
45
|
-
reader = Tb::Reader.new {|body| body.call(aa) }
|
46
|
-
reader.to_tb
|
47
|
-
else
|
48
|
-
header = header_fields
|
49
|
-
arys = aa
|
50
|
-
t = Tb.new(header)
|
51
|
-
arys.each {|ary|
|
52
|
-
ary << nil while ary.length < header.length
|
53
|
-
t.insert_values header, ary
|
54
|
-
}
|
55
|
-
t
|
38
|
+
class HeaderCSVReader < HeaderReader
|
39
|
+
def initialize(io)
|
40
|
+
aryreader = CSV.new(io)
|
41
|
+
super lambda { aryreader.shift }
|
56
42
|
end
|
57
43
|
end
|
58
44
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
def Tb.csv_read_aa(csv)
|
66
|
-
aa = []
|
67
|
-
Tb.csv_stream_input(csv) {|ary| aa << ary }
|
68
|
-
aa
|
69
|
-
end
|
70
|
-
|
71
|
-
class CSVReader
|
72
|
-
def initialize(input)
|
73
|
-
@csv = CSV.new(input)
|
74
|
-
end
|
75
|
-
|
76
|
-
def shift
|
77
|
-
@csv.shift
|
78
|
-
end
|
79
|
-
|
80
|
-
def each
|
81
|
-
while ary = self.shift
|
82
|
-
yield ary
|
83
|
-
end
|
84
|
-
nil
|
45
|
+
class HeaderCSVWriter < HeaderWriter
|
46
|
+
# io is an object which has "<<" method.
|
47
|
+
def initialize(io)
|
48
|
+
super lambda {|ary| io << ary.to_csv}
|
85
49
|
end
|
86
50
|
end
|
87
51
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
def gen.<<(ary)
|
93
|
-
@out << ary.to_csv
|
52
|
+
class NumericCSVReader < NumericReader
|
53
|
+
def initialize(io)
|
54
|
+
aryreader = CSV.new(io)
|
55
|
+
super lambda { aryreader.shift }
|
94
56
|
end
|
95
|
-
yield gen
|
96
|
-
end
|
97
|
-
|
98
|
-
def Tb.csv_encode_row(ary)
|
99
|
-
require 'csv'
|
100
|
-
ary.to_csv
|
101
57
|
end
|
102
58
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
def generate_csv(out='', fields=nil, &block)
|
108
|
-
if fields.nil?
|
109
|
-
fields = list_fields
|
59
|
+
class NumericCSVWriter < NumericWriter
|
60
|
+
# io is an object which has "<<" method.
|
61
|
+
def initialize(io)
|
62
|
+
super lambda {|ary| io << ary.to_csv }
|
110
63
|
end
|
111
|
-
require 'csv'
|
112
|
-
recordids = list_recordids
|
113
|
-
if block_given?
|
114
|
-
recordids = yield(recordids)
|
115
|
-
end
|
116
|
-
Tb.csv_stream_output(out) {|gen|
|
117
|
-
gen << fields
|
118
|
-
recordids.each {|recordid|
|
119
|
-
gen << get_values(recordid, *fields)
|
120
|
-
}
|
121
|
-
}
|
122
|
-
out
|
123
64
|
end
|
65
|
+
|
124
66
|
end
|
data/lib/tb/enumerable.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2012-
|
1
|
+
# Copyright (C) 2012-2014 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions
|
@@ -93,7 +93,7 @@ module Tb::Enumerable
|
|
93
93
|
# creates a new Tb::Enumerator object which have
|
94
94
|
# new field named by _field_ with the value returned by the block.
|
95
95
|
#
|
96
|
-
# t1 = Tb.
|
96
|
+
# t1 = Tb::Enumerator.from_header_and_values %w[a b], [1, 2], [3, 4]
|
97
97
|
# p t1.newfield("x") {|row| row["a"] + row["b"] + 100 }.to_a
|
98
98
|
# #=> [{"x"=>103, "a"=>1, "b"=>2},
|
99
99
|
# # {"x"=>107, "a"=>3, "b"=>4}]
|
@@ -102,11 +102,11 @@ module Tb::Enumerable
|
|
102
102
|
Tb::Enumerator.new {|y|
|
103
103
|
self.with_header {|header|
|
104
104
|
if header
|
105
|
-
y.set_header(
|
105
|
+
y.set_header([field, *header])
|
106
106
|
end
|
107
107
|
}.each {|row|
|
108
108
|
keys = row.keys
|
109
|
-
keys =
|
109
|
+
keys = [field, *keys]
|
110
110
|
vals = row.values
|
111
111
|
vals = [yield(row), *vals]
|
112
112
|
y << Hash[keys.zip(vals)]
|
@@ -176,80 +176,46 @@ module Tb::Enumerable
|
|
176
176
|
natjoin2(tbl2, missing_value, retain_left, retain_right)
|
177
177
|
end
|
178
178
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
tb.define_field(k)
|
185
|
-
end
|
179
|
+
def write_with(writer)
|
180
|
+
header_proc = nil
|
181
|
+
if writer.header_required?
|
182
|
+
header_proc = lambda {|header|
|
183
|
+
writer.header_generator = lambda { header }
|
186
184
|
}
|
187
|
-
|
185
|
+
end
|
186
|
+
body_proc = lambda {|pairs|
|
187
|
+
writer.put_hash pairs
|
188
188
|
}
|
189
|
-
|
189
|
+
header_and_each(header_proc, &body_proc)
|
190
|
+
writer.finish
|
190
191
|
end
|
191
192
|
|
192
193
|
def write_to_csv(io, with_header=true)
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
if !with_header
|
198
|
-
stream = true
|
199
|
-
elsif header0
|
200
|
-
stream = true
|
201
|
-
io.puts Tb.csv_encode_row(header0)
|
202
|
-
else
|
203
|
-
stream = false
|
204
|
-
fgen, fnew = Tb::FileEnumerator.gen_new
|
205
|
-
end
|
206
|
-
}.each {|pairs, header1|
|
207
|
-
pairs = Hash[pairs] unless pairs.respond_to? :has_key?
|
208
|
-
header = header1
|
209
|
-
if stream
|
210
|
-
fs = header.dup
|
211
|
-
while !fs.empty? && !pairs.has_key?(fs.last)
|
212
|
-
fs.pop
|
213
|
-
end
|
214
|
-
ary = fs.map {|f| pairs[f] }
|
215
|
-
io.puts Tb.csv_encode_row(ary)
|
216
|
-
else
|
217
|
-
fgen.call Hash[pairs]
|
218
|
-
end
|
219
|
-
}
|
220
|
-
if !stream
|
221
|
-
if with_header
|
222
|
-
io.puts Tb.csv_encode_row(header)
|
223
|
-
end
|
224
|
-
fnew.call.each {|pairs|
|
225
|
-
fs = header.dup
|
226
|
-
while !fs.empty? && !pairs.has_key?(fs.last)
|
227
|
-
fs.pop
|
228
|
-
end
|
229
|
-
ary = fs.map {|f| pairs[f] }
|
230
|
-
io.puts Tb.csv_encode_row(ary)
|
231
|
-
}
|
194
|
+
if with_header
|
195
|
+
write_with(Tb::HeaderCSVWriter.new(io))
|
196
|
+
else
|
197
|
+
write_with(Tb::NumericCSVWriter.new(io))
|
232
198
|
end
|
233
199
|
end
|
234
200
|
|
235
|
-
def
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
201
|
+
def write_to_tsv(io, with_header=true)
|
202
|
+
if with_header
|
203
|
+
write_with(Tb::HeaderTSVWriter.new(io))
|
204
|
+
else
|
205
|
+
write_with(Tb::NumericTSVWriter.new(io))
|
206
|
+
end
|
240
207
|
end
|
241
208
|
|
242
|
-
def
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
nil
|
209
|
+
def write_to_ltsv(io)
|
210
|
+
write_with(Tb::LTSVWriter.new(io))
|
211
|
+
end
|
212
|
+
|
213
|
+
def write_to_json(io)
|
214
|
+
write_with(Tb::JSONWriter.new(io))
|
215
|
+
end
|
216
|
+
|
217
|
+
def write_to_pnm(io)
|
218
|
+
write_with(Tb::PNMWriter.new(io))
|
253
219
|
end
|
254
220
|
|
255
221
|
def extsort_by(opts={}, &cmpvalue_from)
|
@@ -270,3 +236,11 @@ module Tb::Enumerable
|
|
270
236
|
}
|
271
237
|
end
|
272
238
|
end
|
239
|
+
|
240
|
+
module Tb::EnumerableWithEach
|
241
|
+
include Tb::Enumerable
|
242
|
+
|
243
|
+
def each(&b)
|
244
|
+
header_and_each(nil, &b)
|
245
|
+
end
|
246
|
+
end
|