fat_core 1.5.0 → 1.5.1
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/lib/fat_core/table.rb +86 -8
- data/lib/fat_core/version.rb +1 -1
- data/spec/lib/table_spec.rb +55 -87
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6d9999db399e323a385070ca59d15deb692d65d
|
4
|
+
data.tar.gz: 5bb8ade666435e0c67afeaa293e236082cb19906
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 806ba3e817c5899bd5cb3ffa7a13069d8710c2a29406ae9b6060cf2d30e5d28cc3fc1b983d8b8b3aa9beafc6ceab505695a218c39e8e605ec811bc0c671a3bf7
|
7
|
+
data.tar.gz: e11602a00d01b81bd201092b4bf3cbe8780435d2da3bd3f708f83b2e94677e43a2993b0fc4066fdf8d5d45b258e2516c928c72790e93e84dc77f64714b202f59
|
data/lib/fat_core/table.rb
CHANGED
@@ -227,21 +227,99 @@ module FatCore
|
|
227
227
|
result
|
228
228
|
end
|
229
229
|
|
230
|
-
# Return
|
231
|
-
|
232
|
-
|
233
|
-
|
230
|
+
# Return this table with all duplicate rows eliminated.
|
231
|
+
def distinct
|
232
|
+
result = Table.new
|
233
|
+
uniq_rows = rows.uniq
|
234
|
+
uniq_rows.each do |row|
|
235
|
+
result << row
|
236
|
+
end
|
237
|
+
result
|
238
|
+
end
|
239
|
+
|
240
|
+
def uniq
|
241
|
+
distinct
|
242
|
+
end
|
243
|
+
|
244
|
+
# Return a Table that combines this table with another table. In other
|
245
|
+
# words, return the union of this table with the other. The headers of this
|
246
|
+
# table are used in the result. There must be the same number of columns of
|
247
|
+
# the same type in the two tables, or an exception will be thrown.
|
248
|
+
# Duplicates are eliminated from the result.
|
234
249
|
def union(other)
|
250
|
+
set_operation(other, :+, true)
|
251
|
+
end
|
252
|
+
|
253
|
+
# Return a Table that combines this table with another table. In other
|
254
|
+
# words, return the union of this table with the other. The headers of this
|
255
|
+
# table are used in the result. There must be the same number of columns of
|
256
|
+
# the same type in the two tables, or an exception will be thrown.
|
257
|
+
# Duplicates are not eliminated from the result.
|
258
|
+
def union_all(other)
|
259
|
+
set_operation(other, :+, false)
|
260
|
+
end
|
261
|
+
|
262
|
+
# Return a Table that includes the rows that appear in this table and in
|
263
|
+
# another table. In other words, return the intersection of this table with
|
264
|
+
# the other. The headers of this table are used in the result. There must be
|
265
|
+
# the same number of columns of the same type in the two tables, or an
|
266
|
+
# exception will be thrown. Duplicates are eliminated from the result.
|
267
|
+
def intersect(other)
|
268
|
+
set_operation(other, :intersect, true)
|
269
|
+
end
|
270
|
+
|
271
|
+
# Return a Table that includes the rows that appear in this table and in
|
272
|
+
# another table. In other words, return the intersection of this table with
|
273
|
+
# the other. The headers of this table are used in the result. There must be
|
274
|
+
# the same number of columns of the same type in the two tables, or an
|
275
|
+
# exception will be thrown. Duplicates are not eliminated from the result.
|
276
|
+
def intersect_all(other)
|
277
|
+
set_operation(other, :intersect, false)
|
278
|
+
end
|
279
|
+
|
280
|
+
# Return a Table that includes the rows of this table except for any rows
|
281
|
+
# that are the same as those in another table. In other words, return the
|
282
|
+
# set difference between this table an the other. The headers of this table
|
283
|
+
# are used in the result. There must be the same number of columns of the
|
284
|
+
# same type in the two tables, or an exception will be thrown. Duplicates
|
285
|
+
# are eliminated from the result.
|
286
|
+
def except(other)
|
287
|
+
set_operation(other, :difference, true)
|
288
|
+
end
|
289
|
+
|
290
|
+
# Return a Table that includes the rows of this table except for any rows
|
291
|
+
# that are the same as those in another table. In other words, return the
|
292
|
+
# set difference between this table an the other. The headers of this table
|
293
|
+
# are used in the result. There must be the same number of columns of the
|
294
|
+
# same type in the two tables, or an exception will be thrown. Duplicates
|
295
|
+
# are not eliminated from the result.
|
296
|
+
def except_all(other)
|
297
|
+
set_operation(other, :difference, false)
|
298
|
+
end
|
299
|
+
|
300
|
+
private
|
301
|
+
|
302
|
+
# Apply the set operation given by op between this table and the other table
|
303
|
+
# given in the first argument. If distinct is true, eliminate duplicates
|
304
|
+
# from the result.
|
305
|
+
def set_operation(other, op = :+, distinct = true)
|
235
306
|
unless columns.size == other.columns.size
|
236
|
-
raise 'Cannot apply
|
307
|
+
raise 'Cannot apply a set operation to tables with a different number of columns.'
|
308
|
+
end
|
309
|
+
unless columns.map(&:type) == other.columns.map(&:type)
|
310
|
+
raise 'Cannot apply a set operation to tables with different column types.'
|
237
311
|
end
|
312
|
+
other_rows = other.rows.map { |r| r.replace_keys(headers) }
|
238
313
|
result = Table.new
|
239
|
-
|
240
|
-
|
314
|
+
new_rows = rows.send(op, other_rows)
|
315
|
+
new_rows.each do |row|
|
316
|
+
result << row
|
241
317
|
end
|
242
|
-
result
|
318
|
+
distinct ? result.distinct : result
|
243
319
|
end
|
244
320
|
|
321
|
+
public
|
322
|
+
|
245
323
|
# Return a table that joins this table to another based on one or more join
|
246
324
|
# expressions. There are several possibilities for the join expressions:
|
247
325
|
#
|
data/lib/fat_core/version.rb
CHANGED
data/spec/lib/table_spec.rb
CHANGED
@@ -519,6 +519,61 @@ EOS
|
|
519
519
|
end
|
520
520
|
end
|
521
521
|
|
522
|
+
describe 'union' do
|
523
|
+
it 'should be able to union with a compatible table' do
|
524
|
+
aoh = [
|
525
|
+
{ a: '5', 'Two words' => '20', c: '3,123', d: 'apple' },
|
526
|
+
{ a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
|
527
|
+
{ a: '7', 'Two words' => '8', c: '$1,888', d: 'apple' }
|
528
|
+
]
|
529
|
+
tab1 = Table.new(aoh)
|
530
|
+
aoh2 = [
|
531
|
+
{ t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
|
532
|
+
{ t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
|
533
|
+
{ t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
|
534
|
+
]
|
535
|
+
tab2 = Table.new(aoh2)
|
536
|
+
utab = tab1.union(tab2)
|
537
|
+
expect(utab.rows.size).to eq(6)
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'should throw an exception for union with different sized tables' do
|
541
|
+
aoh = [
|
542
|
+
{ a: '5', 'Two words' => '20', c: '3,123' },
|
543
|
+
{ a: '4', 'Two words' => '5', c: 6412 },
|
544
|
+
{ a: '7', 'Two words' => '8', c: '$1,888' }
|
545
|
+
]
|
546
|
+
tab1 = Table.new(aoh)
|
547
|
+
aoh2 = [
|
548
|
+
{ t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
|
549
|
+
{ t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
|
550
|
+
{ t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
|
551
|
+
]
|
552
|
+
tab2 = Table.new(aoh2)
|
553
|
+
expect {
|
554
|
+
tab1.union(tab2)
|
555
|
+
}.to raise_error(/different number of columns/)
|
556
|
+
end
|
557
|
+
|
558
|
+
it 'should throw an exception for union with different types' do
|
559
|
+
aoh = [
|
560
|
+
{ a: '5', 'Two words' => '20', s: '5143', c: '3123' },
|
561
|
+
{ a: '4', 'Two words' => '5', s: 412, c: 6412 },
|
562
|
+
{ a: '7', 'Two words' => '8', s: '$1821', c: '$1888' }
|
563
|
+
]
|
564
|
+
tab1 = Table.new(aoh)
|
565
|
+
aoh2 = [
|
566
|
+
{ t: '8', 'Two worlds' => '65', s: '2016-01-17', u: 'kiwi' },
|
567
|
+
{ t: '87', 'Two worlds' => '12', s: Date.today, u: 'banana' },
|
568
|
+
{ t: '13', 'Two worlds' => '11', s: '[2015-05-21]', u: 'grape' }
|
569
|
+
]
|
570
|
+
tab2 = Table.new(aoh2)
|
571
|
+
expect {
|
572
|
+
tab1.union(tab2)
|
573
|
+
}.to raise_error(/different column types/)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
522
577
|
describe 'select' do
|
523
578
|
it 'should be able to select by column names' do
|
524
579
|
aoh = [
|
@@ -715,93 +770,6 @@ EOS
|
|
715
770
|
end
|
716
771
|
end
|
717
772
|
|
718
|
-
describe 'set operations' do
|
719
|
-
before :all do
|
720
|
-
aoh = [
|
721
|
-
{ a: '5', 'Two words' => '20', c: '3,123', d: 'apple' },
|
722
|
-
{ a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
|
723
|
-
{ a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
|
724
|
-
{ a: '7', 'Two words' => '8', c: '$1,888', d: 'apple' }
|
725
|
-
]
|
726
|
-
@tab1 = Table.new(aoh)
|
727
|
-
aoh2 = [
|
728
|
-
{ t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
|
729
|
-
{ t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
|
730
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
731
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
732
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
733
|
-
{ t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
|
734
|
-
]
|
735
|
-
@tab2 = Table.new(aoh2)
|
736
|
-
aoh2e = [
|
737
|
-
{ t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
|
738
|
-
{ t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
|
739
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
740
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
741
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
742
|
-
{ t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
|
743
|
-
{ t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
|
744
|
-
]
|
745
|
-
@tab2e = Table.new(aoh2e)
|
746
|
-
# Fewer columns
|
747
|
-
aoh3 = [
|
748
|
-
{ a: '5', 'Two words' => '20', c: '3,123' },
|
749
|
-
{ a: '4', 'Two words' => '5', c: 6412 },
|
750
|
-
{ a: '7', 'Two words' => '8', c: '$1,888' }
|
751
|
-
]
|
752
|
-
@tab3 = Table.new(aoh3)
|
753
|
-
# Different types
|
754
|
-
aoh4 = [
|
755
|
-
{ t: '8', 'Two worlds' => '65', s: '2016-01-17', u: 'kiwi' },
|
756
|
-
{ t: '87', 'Two worlds' => '12', s: Date.today, u: 'banana' },
|
757
|
-
{ t: '13', 'Two worlds' => '11', s: '[2015-05-21]', u: 'grape' }
|
758
|
-
]
|
759
|
-
@tab4 = Table.new(aoh4)
|
760
|
-
end
|
761
|
-
|
762
|
-
it 'union' do
|
763
|
-
utab = @tab1.union(@tab2)
|
764
|
-
expect(utab.size).to eq(6)
|
765
|
-
end
|
766
|
-
|
767
|
-
it 'union_all' do
|
768
|
-
utab = @tab1.union_all(@tab2)
|
769
|
-
expect(utab.size).to eq(10)
|
770
|
-
end
|
771
|
-
|
772
|
-
it 'intersect' do
|
773
|
-
utab = @tab1.intersect(@tab2)
|
774
|
-
expect(utab.size).to eq(1)
|
775
|
-
end
|
776
|
-
|
777
|
-
it 'intersect_all' do
|
778
|
-
utab = @tab1.intersect_all(@tab2)
|
779
|
-
expect(utab.size).to eq(2)
|
780
|
-
end
|
781
|
-
|
782
|
-
it 'except' do
|
783
|
-
utab = @tab2.except(@tab1)
|
784
|
-
expect(utab.size).to eq(4)
|
785
|
-
end
|
786
|
-
|
787
|
-
it 'except_all' do
|
788
|
-
utab = @tab2e.except_all(@tab1)
|
789
|
-
expect(utab.size).to eq(5)
|
790
|
-
end
|
791
|
-
|
792
|
-
it 'should throw an exception for union with different sized tables' do
|
793
|
-
expect {
|
794
|
-
@tab1.union(@tab3)
|
795
|
-
}.to raise_error(/different number of columns/)
|
796
|
-
end
|
797
|
-
|
798
|
-
it 'should throw an exception for union with different types' do
|
799
|
-
expect {
|
800
|
-
@tab1.union(@tab4)
|
801
|
-
}.to raise_error(/different column types/)
|
802
|
-
end
|
803
|
-
end
|
804
|
-
|
805
773
|
describe 'output' do
|
806
774
|
it 'should be able to return itself as an array of arrays' do
|
807
775
|
aoh = [
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fat_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel E. Doherty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simplecov
|