ntable 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +4 -0
- data/Version +1 -1
- data/lib/ntable/construction.rb +40 -25
- data/test/tc_nested_object.rb +30 -0
- metadata +2 -2
data/History.rdoc
CHANGED
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
data/lib/ntable/construction.rb
CHANGED
@@ -153,13 +153,24 @@ module NTable
|
|
153
153
|
# [<tt>:stringify_by_default</tt>]
|
154
154
|
# If set to a Proc, this Proc is used as the default stringification
|
155
155
|
# routine for converting labels for a LabeledAxis.
|
156
|
+
# [<tt>:structure</tt>]
|
157
|
+
# Force the use of the given Structure. Any data that does not fit
|
158
|
+
# into this structure is ignored. When this option is provided,
|
159
|
+
# the :name, :sort, :postprocess_labels, and :postprocess_range
|
160
|
+
# field options are ignored. However, :stringify and :objectify may
|
161
|
+
# still be provided to specify how hash keys should map to labels.
|
156
162
|
|
157
163
|
def from_nested_object(obj_, field_opts_=[], opts_={})
|
164
|
+
if field_opts_.is_a?(::Hash)
|
165
|
+
opts_ = field_opts_
|
166
|
+
field_opts_ = []
|
167
|
+
end
|
158
168
|
axis_data_ = []
|
159
169
|
_populate_nested_axes(axis_data_, 0, obj_)
|
160
170
|
objectify_by_default_ = opts_[:objectify_by_default]
|
161
171
|
stringify_by_default_ = opts_[:stringify_by_default]
|
162
|
-
|
172
|
+
fixed_struct_ = opts_[:structure]
|
173
|
+
struct_ = Structure.new unless fixed_struct_
|
163
174
|
axis_data_.each_with_index do |ai_, i_|
|
164
175
|
field_ = field_opts_[i_] || {}
|
165
176
|
axis_ = nil
|
@@ -184,7 +195,7 @@ module NTable
|
|
184
195
|
klass_ = ObjectAxis
|
185
196
|
else
|
186
197
|
stringify_ = nil unless stringify_.respond_to?(:call)
|
187
|
-
|
198
|
+
h_ = ::Set.new
|
188
199
|
ai_.keys.each do |k_|
|
189
200
|
nv_ = (stringify_ ? stringify_.call(k_) : k_).to_s
|
190
201
|
ai_[k_] = nv_
|
@@ -193,35 +204,39 @@ module NTable
|
|
193
204
|
labels_ = h_.to_a
|
194
205
|
klass_ = LabeledAxis
|
195
206
|
end
|
196
|
-
if
|
197
|
-
if sort_
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
+
if struct_
|
208
|
+
if (sort_ = field_[:sort])
|
209
|
+
if sort_.respond_to?(:call)
|
210
|
+
func_ = sort_
|
211
|
+
elsif sort_ == :string
|
212
|
+
func_ = @string_sort
|
213
|
+
elsif sort_ == :integer
|
214
|
+
func_ = @integer_sort
|
215
|
+
elsif sort_ == :numeric
|
216
|
+
func_ = @numeric_sort
|
217
|
+
else
|
218
|
+
func_ = nil
|
219
|
+
end
|
220
|
+
labels_.sort!(&func_)
|
207
221
|
end
|
208
|
-
|
222
|
+
postprocess_ = field_[:postprocess_labels]
|
223
|
+
labels_ = postprocess_.call(labels_) || labels_ if postprocess_.respond_to?(:call)
|
224
|
+
axis_ = klass_.new(labels_)
|
209
225
|
end
|
210
|
-
postprocess_ = field_[:postprocess_labels]
|
211
|
-
labels_ = postprocess_.call(labels_) || labels_ if postprocess_.respond_to?(:call)
|
212
|
-
axis_ = klass_.new(labels_)
|
213
226
|
when ::Array
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
227
|
+
if struct_
|
228
|
+
range_ = ((ai_[0].to_i)...(ai_[1].to_i))
|
229
|
+
postprocess_ = field_[:postprocess_range]
|
230
|
+
range_ = postprocess_.call(range_) || range_ if postprocess_.respond_to?(:call)
|
231
|
+
ai_[0] = range_.first.to_i
|
232
|
+
ai_[1] = range_.last.to_i
|
233
|
+
ai_[1] += 1 unless range_.exclude_end?
|
234
|
+
axis_ = IndexedAxis.new(ai_[1] - ai_[0], ai_[0])
|
235
|
+
end
|
221
236
|
end
|
222
237
|
struct_.add(axis_, name_) if axis_
|
223
238
|
end
|
224
|
-
table_ = Table.new(struct_, :fill => opts_[:fill])
|
239
|
+
table_ = Table.new(fixed_struct_ || struct_, :fill => opts_[:fill])
|
225
240
|
_populate_nested_values(table_, [], axis_data_, obj_)
|
226
241
|
table_
|
227
242
|
end
|
data/test/tc_nested_object.rb
CHANGED
@@ -233,6 +233,36 @@ module NTable
|
|
233
233
|
end
|
234
234
|
|
235
235
|
|
236
|
+
def test_integer_sort
|
237
|
+
obj_ = {'9' => 1, '10' => 2}
|
238
|
+
t1_ = Table.from_nested_object(obj_, [{:sort => :integer}])
|
239
|
+
assert_equal(['9', '10'], t1_.structure.axis(0).to_a)
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
def test_custom_sort
|
244
|
+
sorter_ = ->(a_, b_){ b_.to_i <=> a_.to_i }
|
245
|
+
obj_ = {'9' => 1, '10' => 2, '11' => 3}
|
246
|
+
t1_ = Table.from_nested_object(obj_, [{:sort => sorter_}])
|
247
|
+
assert_equal(['11', '10', '9'], t1_.structure.axis(0).to_a)
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
def test_custom_object_sort
|
252
|
+
sorter_ = ->(a_, b_){ b_.to_s.to_i <=> a_.to_s.to_i }
|
253
|
+
obj_ = {:'9' => 1, :'10' => 2, :'11' => 3}
|
254
|
+
t1_ = Table.from_nested_object(obj_, [{:sort => sorter_, :objectify => true}])
|
255
|
+
assert_equal([:'11', :'10', :'9'], t1_.structure.axis(0).to_a)
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
def test_fixed_struct
|
260
|
+
struct_ = Structure.add(@indexed_axis_2, 'row').add(@labeled_axis_3, 'col')
|
261
|
+
t1_ = Table.from_nested_object(nil, :structure => struct_, :fill => 0)
|
262
|
+
assert_equal(Table.new(struct_, :load => [0, 0, 0, 0, 0, 0]), t1_)
|
263
|
+
end
|
264
|
+
|
265
|
+
|
236
266
|
end
|
237
267
|
|
238
268
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ntable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-25 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: NTable provides a convenient data structure for storing n-dimensional
|
15
15
|
tabular data. It works with zero-dimensional scalar values, arrays, tables, and
|