tb 0.9 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|