daru_lite 0.1.1 → 0.1.2

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +35 -33
  3. data/lib/daru_lite/data_frame/aggregatable.rb +165 -0
  4. data/lib/daru_lite/data_frame/calculatable.rb +140 -0
  5. data/lib/daru_lite/data_frame/convertible.rb +107 -0
  6. data/lib/daru_lite/data_frame/duplicatable.rb +64 -0
  7. data/lib/daru_lite/data_frame/fetchable.rb +301 -0
  8. data/lib/daru_lite/data_frame/filterable.rb +144 -0
  9. data/lib/daru_lite/data_frame/i_o_able.rb +179 -0
  10. data/lib/daru_lite/data_frame/indexable.rb +168 -0
  11. data/lib/daru_lite/data_frame/iterable.rb +339 -0
  12. data/lib/daru_lite/data_frame/joinable.rb +152 -0
  13. data/lib/daru_lite/data_frame/missable.rb +75 -0
  14. data/lib/daru_lite/data_frame/pivotable.rb +108 -0
  15. data/lib/daru_lite/data_frame/queryable.rb +67 -0
  16. data/lib/daru_lite/data_frame/setable.rb +109 -0
  17. data/lib/daru_lite/data_frame/sortable.rb +241 -0
  18. data/lib/daru_lite/dataframe.rb +138 -2353
  19. data/lib/daru_lite/index/index.rb +13 -0
  20. data/lib/daru_lite/maths/statistics/vector.rb +1 -1
  21. data/lib/daru_lite/vector/aggregatable.rb +9 -0
  22. data/lib/daru_lite/vector/calculatable.rb +78 -0
  23. data/lib/daru_lite/vector/convertible.rb +77 -0
  24. data/lib/daru_lite/vector/duplicatable.rb +17 -0
  25. data/lib/daru_lite/vector/fetchable.rb +175 -0
  26. data/lib/daru_lite/vector/filterable.rb +128 -0
  27. data/lib/daru_lite/vector/indexable.rb +77 -0
  28. data/lib/daru_lite/vector/iterable.rb +95 -0
  29. data/lib/daru_lite/vector/joinable.rb +17 -0
  30. data/lib/daru_lite/vector/missable.rb +124 -0
  31. data/lib/daru_lite/vector/queryable.rb +45 -0
  32. data/lib/daru_lite/vector/setable.rb +47 -0
  33. data/lib/daru_lite/vector/sortable.rb +113 -0
  34. data/lib/daru_lite/vector.rb +36 -932
  35. data/lib/daru_lite/version.rb +1 -1
  36. data/spec/data_frame/aggregatable_example.rb +65 -0
  37. data/spec/data_frame/buildable_example.rb +109 -0
  38. data/spec/data_frame/calculatable_example.rb +135 -0
  39. data/spec/data_frame/convertible_example.rb +180 -0
  40. data/spec/data_frame/duplicatable_example.rb +111 -0
  41. data/spec/data_frame/fetchable_example.rb +476 -0
  42. data/spec/data_frame/filterable_example.rb +250 -0
  43. data/spec/data_frame/indexable_example.rb +221 -0
  44. data/spec/data_frame/iterable_example.rb +465 -0
  45. data/spec/data_frame/joinable_example.rb +106 -0
  46. data/spec/data_frame/missable_example.rb +47 -0
  47. data/spec/data_frame/pivotable_example.rb +297 -0
  48. data/spec/data_frame/queryable_example.rb +92 -0
  49. data/spec/data_frame/setable_example.rb +482 -0
  50. data/spec/data_frame/sortable_example.rb +350 -0
  51. data/spec/dataframe_spec.rb +181 -3289
  52. data/spec/index/index_spec.rb +8 -0
  53. data/spec/vector/aggregatable_example.rb +27 -0
  54. data/spec/vector/calculatable_example.rb +82 -0
  55. data/spec/vector/convertible_example.rb +126 -0
  56. data/spec/vector/duplicatable_example.rb +48 -0
  57. data/spec/vector/fetchable_example.rb +463 -0
  58. data/spec/vector/filterable_example.rb +165 -0
  59. data/spec/vector/indexable_example.rb +201 -0
  60. data/spec/vector/iterable_example.rb +111 -0
  61. data/spec/vector/joinable_example.rb +25 -0
  62. data/spec/vector/missable_example.rb +88 -0
  63. data/spec/vector/queryable_example.rb +91 -0
  64. data/spec/vector/setable_example.rb +300 -0
  65. data/spec/vector/sortable_example.rb +242 -0
  66. data/spec/vector_spec.rb +111 -1805
  67. metadata +86 -2
@@ -0,0 +1,300 @@
1
+ shared_examples_for 'a setable Vector' do |dtype|
2
+ describe "#[]=" do
3
+ context DaruLite::Index do
4
+ let(:vector) do
5
+ DaruLite::Vector.new(
6
+ [1,2,3,4,5],
7
+ name: :yoga,
8
+ index: [:yoda, :anakin, :obi, :padme, :r2d2],
9
+ dtype:
10
+ )
11
+ end
12
+
13
+ it "assigns at the specified index" do
14
+ vector[:yoda] = 666
15
+ expect(vector[:yoda]).to eq(666)
16
+ end
17
+
18
+ it "assigns at the specified Integer index" do
19
+ vector[0] = 666
20
+ expect(vector[:yoda]).to eq(666)
21
+ end
22
+
23
+ it "sets dtype to Array if a nil is assigned" do
24
+ vector[0] = nil
25
+ expect(vector.dtype).to eq(:array)
26
+ end
27
+
28
+ context 'mixed index Vector' do
29
+ let(:vector) do
30
+ DaruLite::Vector.new([1, 2, 3, 4], index: ['a', :a, 0, 66])
31
+ end
32
+
33
+ it "assigns correctly" do
34
+ vector['a'] = 666
35
+ expect(vector['a']).to eq(666)
36
+
37
+ vector[0] = 666
38
+ expect(vector[0]).to eq(666)
39
+
40
+ vector[3] = 666
41
+ expect(vector[3]).to eq(666)
42
+
43
+ expect(vector).to eq(
44
+ DaruLite::Vector.new(
45
+ [666, 2, 666, 666],
46
+ index: ['a', :a, 0, 66])
47
+ )
48
+ end
49
+ end
50
+ end
51
+
52
+ context DaruLite::MultiIndex do
53
+ let(:tuples) do
54
+ [
55
+ [:a,:one,:bar],
56
+ [:a,:one,:baz],
57
+ [:a,:two,:bar],
58
+ [:a,:two,:baz],
59
+ [:b,:one,:bar],
60
+ [:b,:two,:bar],
61
+ [:b,:two,:baz],
62
+ [:b,:one,:foo],
63
+ [:c,:one,:bar],
64
+ [:c,:one,:baz],
65
+ [:c,:two,:foo],
66
+ [:c,:two,:bar]
67
+ ]
68
+ end
69
+ let(:multi_index) { DaruLite::MultiIndex.from_tuples(tuples) }
70
+ let(:vector) do
71
+ DaruLite::Vector.new(
72
+ Array.new(12) { |i| i },
73
+ index: multi_index,
74
+ dtype:,
75
+ name: :mi_vector
76
+ )
77
+ end
78
+
79
+ it "assigns all lower layer indices when specified a first layer index" do
80
+ vector[:b] = 69
81
+ expect(vector).to eq(
82
+ DaruLite::Vector.new([0, 1, 2, 3, 69, 69, 69, 69, 8, 9, 10, 11],
83
+ index: multi_index,
84
+ name: :top_layer_assignment,
85
+ dtype:
86
+ )
87
+ )
88
+ end
89
+
90
+ it "assigns all lower indices when specified first and second layer index" do
91
+ vector[:b, :one] = 69
92
+ expect(vector).to eq(
93
+ DaruLite::Vector.new([0, 1, 2, 3, 69, 5, 6, 69, 8, 9, 10, 11],
94
+ index: multi_index,
95
+ name: :second_layer_assignment,
96
+ dtype:
97
+ )
98
+ )
99
+ end
100
+
101
+ it "assigns just the precise value when specified complete tuple" do
102
+ vector[:b, :one, :foo] = 69
103
+ expect(vector).to eq(
104
+ DaruLite::Vector.new([0, 1, 2, 3, 4, 5, 6, 69, 8, 9, 10, 11],
105
+ index: multi_index,
106
+ name: :precise_assignment,
107
+ dtype:
108
+ )
109
+ )
110
+ end
111
+
112
+ it "assigns correctly when numeric index" do
113
+ vector[7] = 69
114
+ expect(vector).to eq(
115
+ DaruLite::Vector.new([0, 1, 2, 3, 4, 5, 6, 69, 8, 9, 10, 11],
116
+ index: multi_index,
117
+ name: :precise_assignment,
118
+ dtype:
119
+ )
120
+ )
121
+ end
122
+
123
+ it "fails predictably on unknown index" do
124
+ expect { vector[:d] = 69 }.to raise_error(IndexError)
125
+ expect { vector[:b, :three] = 69 }.to raise_error(IndexError)
126
+ expect { vector[:b, :two, :test] = 69 }.to raise_error(IndexError)
127
+ end
128
+ end
129
+
130
+ context DaruLite::CategoricalIndex do
131
+ subject { vector }
132
+
133
+ context "non-numerical index" do
134
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, :b, :a, :a, :c] }
135
+ let (:vector) { DaruLite::Vector.new 'a'..'e', index: idx }
136
+
137
+ context "single category" do
138
+ context "multiple instances" do
139
+ before { vector[:a] = 'x' }
140
+
141
+ its(:size) { is_expected.to eq 5 }
142
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'e'] }
143
+ its(:index) { is_expected.to eq idx }
144
+ end
145
+
146
+ context "single instance" do
147
+ before { vector[:b] = 'x' }
148
+
149
+ its(:size) { is_expected.to eq 5 }
150
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
151
+ its(:index) { is_expected.to eq idx }
152
+ end
153
+ end
154
+
155
+ context "multiple categories" do
156
+ before { vector[:a, :c] = 'x' }
157
+
158
+ its(:size) { is_expected.to eq 5 }
159
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'x'] }
160
+ its(:index) { is_expected.to eq idx }
161
+ end
162
+
163
+ context "multiple positional indexes" do
164
+ before { vector[0, 1, 2] = 'x' }
165
+
166
+ its(:size) { is_expected.to eq 5 }
167
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
168
+ its(:index) { is_expected.to eq idx }
169
+ end
170
+
171
+ context "single positional index" do
172
+ before { vector[1] = 'x' }
173
+
174
+ its(:size) { is_expected.to eq 5 }
175
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
176
+ its(:index) { is_expected.to eq idx }
177
+ end
178
+
179
+ context "invalid category" do
180
+ it { expect { vector[:x] = 'x' }.to raise_error IndexError }
181
+ end
182
+
183
+ context "invalid positional index" do
184
+ it { expect { vector[30] = 'x'}.to raise_error IndexError }
185
+ end
186
+ end
187
+
188
+ context "numerical index" do
189
+ let (:idx) { DaruLite::CategoricalIndex.new [1, 1, 2, 2, 3] }
190
+ let (:vector) { DaruLite::Vector.new 'a'..'e', index: idx }
191
+
192
+ context "single category" do
193
+ before { vector[1] = 'x' }
194
+
195
+ its(:size) { is_expected.to eq 5 }
196
+ its(:to_a) { is_expected.to eq ['x', 'x', 'c', 'd', 'e'] }
197
+ its(:index) { is_expected.to eq idx }
198
+ end
199
+
200
+ context "multiple categories" do
201
+ before { vector[1, 2] = 'x' }
202
+
203
+ its(:size) { is_expected.to eq 5 }
204
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'x', 'e'] }
205
+ its(:index) { is_expected.to eq idx }
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ describe "#set_at" do
212
+ context DaruLite::Index do
213
+ let (:idx) { DaruLite::Index.new [1, 0, :c] }
214
+ let (:dv) { DaruLite::Vector.new ['a', 'b', 'c'], index: idx }
215
+
216
+ context "single position" do
217
+ subject { dv }
218
+ before { dv.set_at [1], 'x' }
219
+
220
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c'] }
221
+ end
222
+
223
+ context "multiple positions" do
224
+ subject { dv }
225
+ before { dv.set_at [0, 2], 'x' }
226
+
227
+ its(:to_a) { is_expected.to eq ['x', 'b', 'x'] }
228
+ end
229
+
230
+ context "invalid position" do
231
+ it { expect { dv.set_at [3], 'x' }.to raise_error IndexError }
232
+ end
233
+
234
+ context "invalid positions" do
235
+ it { expect { dv.set_at [2, 3], 'x' }.to raise_error IndexError }
236
+ end
237
+ end
238
+
239
+ context DaruLite::MultiIndex do
240
+ let(:idx) do
241
+ DaruLite::MultiIndex.from_tuples [
242
+ [:a,:one,:bar],
243
+ [:a,:one,:baz],
244
+ [:b,:two,:bar],
245
+ [:a,:two,:baz],
246
+ ]
247
+ end
248
+ let(:dv) { DaruLite::Vector.new 1..4, index: idx }
249
+
250
+ context "single position" do
251
+ subject { dv }
252
+ before { dv.set_at [1], 'x' }
253
+
254
+ its(:to_a) { is_expected.to eq [1, 'x', 3, 4] }
255
+ end
256
+
257
+ context "multiple positions" do
258
+ subject { dv }
259
+ before { dv.set_at [2, 3], 'x' }
260
+
261
+ its(:to_a) { is_expected.to eq [1, 2, 'x', 'x'] }
262
+ end
263
+
264
+ context "invalid position" do
265
+ it { expect { dv.set_at [4], 'x' }.to raise_error IndexError }
266
+ end
267
+
268
+ context "invalid positions" do
269
+ it { expect { dv.set_at [2, 4], 'x' }.to raise_error IndexError }
270
+ end
271
+ end
272
+
273
+ context DaruLite::CategoricalIndex do
274
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, 1, 1, :a, :c] }
275
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
276
+
277
+ context "multiple positional indexes" do
278
+ subject { dv }
279
+ before { dv.set_at [0, 1, 2], 'x' }
280
+
281
+ its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
282
+ end
283
+
284
+ context "single positional index" do
285
+ subject { dv }
286
+ before { dv.set_at [1], 'x' }
287
+
288
+ its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
289
+ end
290
+
291
+ context "invalid position" do
292
+ it { expect { dv.set_at [5], 'x' }.to raise_error IndexError }
293
+ end
294
+
295
+ context "invalid positions" do
296
+ it { expect { dv.set_at [2, 5], 'x' }.to raise_error IndexError }
297
+ end
298
+ end
299
+ end
300
+ end
@@ -0,0 +1,242 @@
1
+ shared_examples_for 'a sortable Vector' do |dtype|
2
+ describe "#reorder!" do
3
+ subject { vector_with_dtype.reorder!([3, 2, 1, 0]) }
4
+
5
+ let(:vector_with_dtype) do
6
+ DaruLite::Vector.new(
7
+ [1, 2, 3, 4],
8
+ index: [:a, :b, :c, :d],
9
+ dtype:
10
+ )
11
+ end
12
+ let(:arranged_vector) do
13
+ DaruLite::Vector.new([4,3,2,1], index: [:d, :c, :b, :a], dtype:)
14
+ end
15
+
16
+ before { subject }
17
+
18
+ it "rearranges with passed order" do
19
+ expect(vector_with_dtype).to eq arranged_vector
20
+ end
21
+
22
+ it "doesn't change dtype" do
23
+ expect(vector_with_dtype.data.class).to eq arranged_vector.data.class
24
+ end
25
+ end
26
+
27
+
28
+ context "#sort" do
29
+ context DaruLite::Index do
30
+ let(:vector) do
31
+ DaruLite::Vector.new([33, 2, 15, 332, 1], name: :dv, index: [:a, :b, :c, :d, :e])
32
+ end
33
+
34
+ it "sorts the vector with defaults and returns a new vector, preserving indexing" do
35
+ expect(vector.sort).to eq(
36
+ DaruLite::Vector.new([1,2,15,33,332], name: :dv, index: [:e, :b, :c, :a, :d])
37
+ )
38
+ end
39
+
40
+ it "sorts the vector in descending order" do
41
+ expect(vector.sort(ascending: false)).to eq(
42
+ DaruLite::Vector.new([332,33,15,2,1], name: :dv, index: [:d, :a, :c, :b, :e])
43
+ )
44
+ end
45
+
46
+ context 'when a block is passed' do
47
+ subject { vector.sort { |a,b| a.length <=> b.length } }
48
+
49
+ let(:vector) { DaruLite::Vector.new ["My Jazz Guitar", "Jazz", "My", "Guitar"] }
50
+
51
+ it "sorts vector accordingly" do
52
+ expect(subject).to eq(
53
+ DaruLite::Vector.new(["My", "Jazz", "Guitar", "My Jazz Guitar"], index: [2, 1, 3, 0])
54
+ )
55
+ end
56
+ end
57
+
58
+ context 'when vector contains nils and numeric data' do
59
+ let(:vector) { DaruLite::Vector.new([22, 4, nil, 111, nil, 2]) }
60
+
61
+ it "places nils near the beginning of the vector when sorting ascendingly" do
62
+ expect(vector.sort).to eq(
63
+ DaruLite::Vector.new([nil, nil, 2, 4, 22, 111], index: [2, 4, 5, 1, 0, 3])
64
+ )
65
+ end if dtype == :array
66
+
67
+ it "places nils near the beginning of the vector when sorting descendingly" do
68
+ expect(vector.sort(ascending: false)).to eq(
69
+ DaruLite::Vector.new [111, 22, 4, 2, nil, nil], index: [3, 0, 1, 5, 4, 2]
70
+ )
71
+ end
72
+ end
73
+
74
+ context 'when vector contains nils and non-numeric data' do
75
+ let(:vector) { DaruLite::Vector.new(['a','b', nil, 'aa', '1234', nil]) }
76
+
77
+ it "correctly sorts vector in ascending order" do
78
+ expect(vector.sort(ascending: true)).to eq(
79
+ DaruLite::Vector.new([nil, nil, '1234', 'a', 'aa', 'b'], index: [2, 5, 4, 0, 3, 1])
80
+ )
81
+ end
82
+
83
+ it "correctly sorts vector in descending order" do
84
+ expect(vector.sort(ascending: false)).to eq(
85
+ DaruLite::Vector.new(['b', 'aa', 'a', '1234', nil, nil], index: [1, 3, 0, 4, 5, 2])
86
+ )
87
+ end
88
+ end
89
+ end
90
+
91
+ context DaruLite::MultiIndex do
92
+ let(:multi_index) do
93
+ DaruLite::MultiIndex.from_tuples([
94
+ [:a, :one, :foo],
95
+ [:a, :two, :bar],
96
+ [:b, :one, :bar],
97
+ [:b, :two, :baz],
98
+ [:b, :three, :bar]
99
+ ])
100
+ end
101
+ let(:vector) do
102
+ DaruLite::Vector.new(
103
+ [44, 22, 111, 0, -56],
104
+ index: multi_index,
105
+ name: :unsorted,
106
+ dtype:
107
+ )
108
+ end
109
+
110
+ it "sorts vector" do
111
+ mi_asc = DaruLite::MultiIndex.from_tuples([
112
+ [:b, :three, :bar],
113
+ [:b, :two, :baz],
114
+ [:a, :two, :bar],
115
+ [:a, :one, :foo],
116
+ [:b, :one, :bar]
117
+ ])
118
+ expect(vector.sort).to eq(
119
+ DaruLite::Vector.new([-56,0,22,44,111], index: mi_asc, name: :ascending, dtype:)
120
+ )
121
+ end
122
+
123
+ it "sorts in descending" do
124
+ mi_dsc = DaruLite::MultiIndex.from_tuples([
125
+ [:b, :one, :bar],
126
+ [:a, :one, :foo],
127
+ [:a, :two, :bar],
128
+ [:b, :two, :baz],
129
+ [:b, :three, :bar]
130
+ ])
131
+ expect(vector.sort(ascending: false)).to eq(
132
+ DaruLite::Vector.new([111, 44, 22, 0, -56], index: mi_dsc, name: :descending, dtype:)
133
+ )
134
+ end
135
+
136
+ it "sorts using the supplied block" do
137
+ mi_abs = DaruLite::MultiIndex.from_tuples([
138
+ [:b, :two, :baz],
139
+ [:a, :two, :bar],
140
+ [:a, :one, :foo],
141
+ [:b, :three, :bar],
142
+ [:b, :one, :bar]
143
+ ])
144
+ expect(vector.sort { |a,b| a.abs <=> b.abs }).to eq(
145
+ DaruLite::Vector.new([0, 22, 44, -56, 111], index: mi_abs, name: :sort_abs, dtype:)
146
+ )
147
+ end
148
+ end
149
+
150
+ context DaruLite::CategoricalIndex do
151
+ let(:idx) { DaruLite::CategoricalIndex.new [:a, 1, :a, 1, :c] }
152
+ let(:dv_numeric) { DaruLite::Vector.new [4, 5, 3, 2, 1], index: idx }
153
+ let(:dv_string) { DaruLite::Vector.new ['xxxx', 'zzzzz', 'ccc', 'bb', 'a'], index: idx }
154
+ let(:dv_nil) { DaruLite::Vector.new [3, nil, 2, 1, -1], index: idx }
155
+
156
+ context "increasing order" do
157
+ context "numeric" do
158
+ subject { dv_numeric.sort }
159
+
160
+ its(:size) { is_expected.to eq 5 }
161
+ its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
162
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
163
+ end
164
+
165
+ context "non-numeric" do
166
+ subject { dv_string.sort }
167
+
168
+ its(:size) { is_expected.to eq 5 }
169
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
170
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
171
+ end
172
+
173
+ context "block" do
174
+ subject { dv_string.sort { |a, b| a.length <=> b.length } }
175
+
176
+ its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
177
+ its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
178
+ end
179
+
180
+ context "nils" do
181
+ subject { dv_nil.sort }
182
+
183
+ its(:to_a) { is_expected.to eq [nil, -1, 1, 2, 3] }
184
+ its(:'index.to_a') { is_expected.to eq [1, :c, 1, :a, :a] }
185
+ end
186
+ end
187
+
188
+ context "decreasing order" do
189
+ context "numeric" do
190
+ subject { dv_numeric.sort(ascending: false) }
191
+
192
+ its(:size) { is_expected.to eq 5 }
193
+ its(:to_a) { is_expected.to eq [5, 4, 3, 2, 1] }
194
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
195
+ end
196
+
197
+ context "non-numeric" do
198
+ subject { dv_string.sort(ascending: false) }
199
+
200
+ its(:size) { is_expected.to eq 5 }
201
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
202
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
203
+ end
204
+
205
+ context "block" do
206
+ subject do
207
+ dv_string.sort(ascending: false) { |a, b| a.length <=> b.length }
208
+ end
209
+
210
+ its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
211
+ its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
212
+ end
213
+
214
+ context "nils" do
215
+ subject { dv_nil.sort(ascending: false) }
216
+
217
+ its(:to_a) { is_expected.to eq [3, 2, 1, -1, nil] }
218
+ its(:'index.to_a') { is_expected.to eq [:a, :a, 1, :c, 1] }
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ describe "#sort_by_index" do
225
+ let(:asc) { vector.sort_by_index }
226
+ let(:desc) { vector.sort_by_index(ascending: false) }
227
+
228
+ context 'numeric vector' do
229
+ let(:vector) { DaruLite::Vector.new [11, 13, 12], index: [23, 21, 22] }
230
+
231
+ specify { expect(asc.to_a).to eq [13, 12, 11] }
232
+ specify { expect(desc.to_a).to eq [11, 12, 13] }
233
+ end
234
+
235
+ context 'mix variable type index' do
236
+ let(:vector) { DaruLite::Vector.new [11, Float::NAN, nil], index: [21, 23, 22] }
237
+
238
+ specify { expect(asc.to_a).to eq [11, nil, Float::NAN] }
239
+ specify { expect(desc.to_a).to eq [Float::NAN, nil, 11] }
240
+ end
241
+ end
242
+ end