deep-hash-struct 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d75b9bdee86a1e833867d5f5c09a39af09dbe262
4
- data.tar.gz: a9b9534aeb425c24a0cabc04f03ce417876c344f
3
+ metadata.gz: e9756a09b00c5be33e8b9196673a4439b3da918a
4
+ data.tar.gz: 86660d00023b2713ee316c11f71ef4e3df88fcff
5
5
  SHA512:
6
- metadata.gz: 5d3676edb4c79c1dfcd232c9c550b00afd1acba038c39b389f719239c2948fb843c34be45e70ffb0e7d1389c01aa81c96026e158cd18668362955e48702d46bf
7
- data.tar.gz: c882419641decdce45a9bbb6a6ae139ef8ca76730785b8c1b449e02da0b78f56a21a403dc36f867635e54da9257ad5b65425161a2f0967716b4ba1078d767ae9
6
+ metadata.gz: 2e1b5ad03894c35f73a2efa5887ebad6b072375cec42c63cbb7e4ad3d739707a8ba0bc4cb4610d4035069cd8e0f399db4830e7c37a282ecf5a79cf8e4f313939
7
+ data.tar.gz: 1ddc24f2c752217c34a865ee3ff5440d7542e273b94bfd40e06ce2a7973b89f664005a785c5075ce5d43fe3f7412a0646121841031e5dae50d474a100df5a597
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 TODO: Write your name
3
+ Copyright (c) 2017 by etiopiamokamame
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -19,8 +19,10 @@ Or install it yourself as:
19
19
 
20
20
  $ gem install deep-hash-struct
21
21
 
22
- ## Usage
22
+ ## Wrapper Class Usage
23
+ The basic usage is the same as Hash Class.
23
24
 
25
+ ### Basic
24
26
  ```ruby
25
27
  wrapper = Deep::Hash::Struct::Wrapper.new
26
28
  wrapper.a = 1
@@ -30,6 +32,850 @@ wrapper[:c].b = 4
30
32
  wrapper.to_h # => {:a=>1, :b=>{:a=>2}, :c=>{:a=>3, :b=>4}}
31
33
  ```
32
34
 
35
+ ### Block
36
+ ```ruby
37
+ wrapper.a do
38
+ 1 + 1
39
+ end
40
+ wrapper.a # => 2
41
+
42
+ wrapper.b do
43
+ { c: 3 }
44
+ end
45
+ wrapper.b.c # => 3
46
+ ```
47
+
48
+ ### #dig
49
+ ```ruby
50
+ wrapper.a.b = { c: 1, d: [1, 2, [3, 4, 5]] }
51
+ wrapper.dig(:a, :b, :c) # => 1
52
+ wrapper.dig(:a, :b, :d, 2, 0) # => 3
53
+ wrapper.dig(:a, :c).blank? # => true
54
+ ```
55
+
56
+ ### #merge
57
+ #### Deep::Hash::Struct::Wrapper Class
58
+ ```ruby
59
+ wrapper.a = 1
60
+ wrapper.b = 2
61
+ wrapper.c.a = 3
62
+ wrapper.c.b = 4
63
+ wrapper.c.c = 5
64
+
65
+ other = wrapper.class.new
66
+ other.a = 6
67
+ other.b = 7
68
+ other.c.a = 8
69
+
70
+ wrapper.merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8}}
71
+ ```
72
+
73
+ #### Hash Class
74
+ ```ruby
75
+ wrapper.a = 1
76
+ wrapper.b = 2
77
+ wrapper.c.a = 3
78
+ wrapper.c.b = 4
79
+ wrapper.c.c = 5
80
+
81
+ other = {}
82
+ other[:a] = 6
83
+ other[:b] = 7
84
+ other[:c] = {}
85
+ other[:c][:a] = 8
86
+
87
+ wrapper.merge(other).to_h #=> {:a=>6, :b=>7, :c=>{:a=>8}}
88
+ ```
89
+
90
+ ### #merge! #update
91
+ bang merge method
92
+
93
+ ### #deep_merge
94
+ #### Deep::Hash::Struct::Wrapper Class
95
+ ```ruby
96
+ wrapper.a = 1
97
+ wrapper.b = 2
98
+ wrapper.c.a = 3
99
+ wrapper.c.b = 4
100
+ wrapper.c.c = 5
101
+
102
+ other = wrapper.class.new
103
+ other.a = 6
104
+ other.b = 7
105
+ other.c.a = 8
106
+
107
+ wrapper.deep_merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8, :b=>4, :c=>5}}
108
+ ```
109
+
110
+ #### Hash Class
111
+ ```ruby
112
+ wrapper.a = 1
113
+ wrapper.b = 2
114
+ wrapper.c.a = 3
115
+ wrapper.c.b = 4
116
+ wrapper.c.c = 5
117
+
118
+ other = {}
119
+ other[:a] = 6
120
+ other[:b] = 7
121
+ other[:c] = {}
122
+ other[:c][:a] = 8
123
+
124
+ wrapper.deep_merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8, :b=>4, :c=>5}}
125
+ ```
126
+
127
+ ### #deep_merge!
128
+ bang deep_merge method
129
+
130
+ ### #reverse_merge
131
+ #### Deep::Hash::Struct::Wrapper Class
132
+ ```ruby
133
+ wrapper.a = 1
134
+ wrapper.b = 2
135
+ wrapper.c.a = 3
136
+ wrapper.c.b = 4
137
+ wrapper.c.c = 5
138
+
139
+ other = wrapper.class.new
140
+ other.a = 6
141
+ other.b = 7
142
+ other.c.a = 8
143
+ other.d.a = 9
144
+
145
+ wrapper.reverse_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5}, :d=>{:a=>9}}
146
+ ```
147
+
148
+ #### Hash Class
149
+ ```ruby
150
+ wrapper.a = 1
151
+ wrapper.b = 2
152
+ wrapper.c.a = 3
153
+ wrapper.c.b = 4
154
+ wrapper.c.c = 5
155
+
156
+ other = {}
157
+ other[:a] = 6
158
+ other[:b] = 7
159
+ other[:c] = {}
160
+ other[:c][:a] = 8
161
+ other[:d] = {}
162
+ other[:d][:a] = 9
163
+
164
+ wrapper.reverse_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5}, :d=>{:a=>9}}
165
+ ```
166
+
167
+ ### #reverse_merge!
168
+ bang reverse_merge method
169
+
170
+ ### #reverse_deep_merge
171
+ #### Deep::Hash::Struct::Wrapper Class
172
+ ```ruby
173
+ wrapper.a = 1
174
+ wrapper.b = 2
175
+ wrapper.c.a = 3
176
+ wrapper.c.b = 4
177
+ wrapper.c.c = 5
178
+
179
+ other = wrapper.class.new
180
+ other.a = 6
181
+ other.b = 7
182
+ other.c.a = 8
183
+ other.c.d = 9
184
+
185
+ wrapper.reverse_deep_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5, :d=>9}}
186
+ ```
187
+
188
+ #### Hash Class
189
+ ```ruby
190
+ wrapper.a = 1
191
+ wrapper.b = 2
192
+ wrapper.c.a = 3
193
+ wrapper.c.b = 4
194
+ wrapper.c.c = 5
195
+
196
+ other = {}
197
+ other[:a] = 6
198
+ other[:b] = 7
199
+ other[:c] = {}
200
+ other[:c][:a] = 8
201
+ other[:c][:d] = 9
202
+
203
+ wrapper.reverse_deep_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5, :d=>9}}
204
+ ```
205
+
206
+ ### #reverse_deep_merge!
207
+ bang reverse_deep_merge method
208
+
209
+ ### #fetch
210
+ ```ruby
211
+ wrapper.a = 1
212
+ wrapper.fetch(:a, :not_found) # => 1
213
+ wrapper.fetch(:a) { |k| "#{k} not found" } # => 1
214
+ wrapper.fetch(:b) # => nil
215
+ wrapper.fetch(:b, :not_found) # => :not_found
216
+ wrapper.fetch(:b) { |k| "#{k} not found" } # => "b not found"
217
+ ```
218
+
219
+ ### #default
220
+ ```ruby
221
+ wrapper.a.default = 0
222
+ wrapper.b.default = []
223
+ wrapper.a.a # => 0
224
+ wrapper.b.a # => []
225
+ ```
226
+
227
+ ### #map_key
228
+ ```ruby
229
+ wrapper.a = 1
230
+ wrapper.b = 2
231
+ wrapper.c = 3
232
+ wrapper.map_key { |k| [k] } # => [[:a], [:b], [:c]]
233
+ ```
234
+
235
+ ### #map_value
236
+ ```ruby
237
+ wrapper.a = 1
238
+ wrapper.b = 2
239
+ wrapper.c = 3
240
+ wrapper.map_value { |k| [k] } # => [[1], [2], [3]]
241
+ ```
242
+
243
+ ### #fetch_values
244
+ ```ruby
245
+ wrapper.a = 1
246
+ wrapper.b = 2
247
+ wrapper.fetch_values(:a, :b) # => [1, 2]
248
+ wrapper.fetch_values(:a, :c) # => KeyError: key not found: :c
249
+ wrapper.fetch_values(:a, :c) { |k| k.upcase } # => [1, :C]
250
+ ```
251
+
252
+ ### #values_at
253
+ ```ruby
254
+ wrapper.a = 1
255
+ wrapper.b = 2
256
+ wrapper.c = 3
257
+ wrapper.values_at(:a, :b, :d) # => [1, 2, nil]
258
+ ```
259
+
260
+ ### #invert
261
+ ```ruby
262
+ wrapper.a = 1
263
+ wrapper.b = 2
264
+ wrapper.c = 3
265
+ wrapper.invert # => {1=>:a, 2=>:b, 3=>:c}
266
+ ```
267
+
268
+ ### #delete
269
+ ```ruby
270
+ wrapper.a = 1
271
+ wrapper.b = 2
272
+ wrapper.c = 3
273
+ wrapper.delete(:a) # => 1
274
+ wrapper.keys # => [:b, :c]
275
+ ```
276
+
277
+ ### #delete_if
278
+ ```ruby
279
+ wrapper.a = 1
280
+ wrapper.b = 2
281
+ wrapper.c = 3
282
+ wrapper.delete_if{ |k, v| k == :a || v == 2 }.to_h # => {:c=>3}
283
+ wrapper.keys # => [:c]
284
+ ```
285
+
286
+ ### #reject
287
+ ```ruby
288
+ wrapper.a = 1
289
+ wrapper.b = 2
290
+ wrapper.c = 3
291
+ wrapper.reject { |k, v| v > 2 }.to_h # => {:a=>1, :b=>2}
292
+ ```
293
+
294
+ ### #reject!
295
+ bang reject method
296
+
297
+ ### #clear
298
+ ```ruby
299
+ wrapper.a = 1
300
+ wrapper.b = 2
301
+ wrapper.c = 3
302
+ wrapper.clear
303
+ wrapper.to_h # => {}
304
+ ```
305
+
306
+ ### #flatten
307
+ ```ruby
308
+ wrapper.a = 1
309
+ wrapper.b = 2
310
+ wrapper.c.a = 3
311
+ wrapper.c.b = 4
312
+ wrapper.c.c = 5
313
+ wrapper.flatten # => [:a, 1, :b, 2, :c, {:a=>3, :b=>4, :c=>5}]
314
+ ```
315
+
316
+ ### #has_key? #include?
317
+ ```ruby
318
+ wrapper.a = 1
319
+ wrapper.has_key?(:a) # => true
320
+ wrapper.has_key?(:b) # => false
321
+ ```
322
+
323
+ ### #has_keys?
324
+ ```ruby
325
+ wrapper.a = 1
326
+ wrapper.b = 2
327
+ wrapper.c.a = 3
328
+ wrapper.has_keys?(:a) # => true
329
+ wrapper.has_keys?(:c, :a) # => true
330
+ wrapper.has_keys?(:d) # => false
331
+ wrapper.has_keys?(:c, :b) # => false
332
+ wrapper.has_keys?(:d, :a) # => false
333
+ ```
334
+
335
+ ### #exclude?
336
+ ```ruby
337
+ wrapper.a = 1
338
+ wrapper.exclude?(:a) # => false
339
+ wrapper.exclude?(:d) # => true
340
+ ```
341
+
342
+ ### #sort
343
+ ```ruby
344
+ wrapper.c = 1
345
+ wrapper.b = 2
346
+ wrapper.a = 3
347
+ wrapper.sort # => [[:a, 3], [:b, 2], [:c, 1]]
348
+ ```
349
+
350
+ ### #shift
351
+ ```ruby
352
+ wrapper.a = 1
353
+ wrapper.b = 2
354
+ wrapper.c = 3
355
+ wrapper.shift # => [:a, 1]
356
+ wrapper.to_h # => {:b=>2, :c=>3}
357
+ ```
358
+
359
+ ### #compact
360
+ ```ruby
361
+ wrapper.a = 1
362
+ wrapper.b = nil
363
+ wrapper.c.a = 2
364
+ wrapper.c.b = ""
365
+ wrapper.d.a = nil
366
+
367
+ wrapper.keys # => [:a, :b, :c, :d]
368
+ wrapper.c.keys # => [:a, :b]
369
+ wrapper.compact.keys # => [:a, :c, :d]
370
+ wrapper.compact.c.keys # => [:a, :b]
371
+ wrapper.keys # => [:a, :b, :c, :d]
372
+ wrapper.c.keys # => [:a, :b]
373
+ ```
374
+
375
+ ### #compact!
376
+ bang compact method
377
+
378
+ ### #deep_compact
379
+ ```ruby
380
+ wrapper.a = 1
381
+ wrapper.b = nil
382
+ wrapper.c.a = 2
383
+ wrapper.c.b = ""
384
+ wrapper.d.a = nil
385
+
386
+ wrapper.keys # => [:a, :b, :c, :d]
387
+ wrapper.c.keys # => [:a, :b]
388
+ wrapper.deep_compact.keys # => [:a, :c]
389
+ wrapper.deep_compact.c.keys # => [:a, :b]
390
+ wrapper.keys # => [:a, :b, :c, :d]
391
+ wrapper.c.keys # => [:a, :b]
392
+ ```
393
+
394
+ ### #deep_compact!
395
+ bang deep_compact method
396
+
397
+ ### #slice
398
+ ```ruby
399
+ wrapper.a = 1
400
+ wrapper.b = 2
401
+ wrapper.c = 3
402
+
403
+ wrapper.slice(:a, :b).to_h # => {:a=>1, :b=>2}
404
+ wrapper.slice(:b, :c).to_h # => {:b=>2, :c=>3}
405
+ wrapper.slice(:c, :d).to_h # => {:c=>3}
406
+ wrapper.to_h # => {:a=>1, :b=>2, :c=>3}
407
+ ```
408
+
409
+ ### #slice!
410
+ bang slice method
411
+
412
+ ### #to_hash #to_h
413
+ ```ruby
414
+ wrapper.a = 1
415
+ wrapper.b = 2
416
+ wrapper.c.a = 3
417
+
418
+ wrapper.to_hash # => {:a=>1, :b=>2, :c=>{:a=>3}}
419
+ ```
420
+
421
+ ### #to_json
422
+ ```ruby
423
+ wrapper.a = 1
424
+ wrapper.b = 2
425
+ wrapper.c.a = 3
426
+ wrapper.to_json # => "{\"a\":1,\"b\":2,\"c\":{\"a\":3}}"
427
+ ```
428
+
429
+ ### #max_stages
430
+ ```ruby
431
+ wrapper.a = 1
432
+ wrapper.b.a = 2
433
+ wrapper.b.b = 3
434
+ wrapper.c.a.b = 4
435
+ wrapper.c.a.c = 5
436
+ wrapper.c.a.d = 6
437
+
438
+ wrapper.max_stages # => 3
439
+ wrapper.b.max_stages # => 1
440
+ wrapper.c.max_stages # => 2
441
+ ```
442
+
443
+ ### #min_stages
444
+ ```ruby
445
+ wrapper.a = 1
446
+ wrapper.b.a = 2
447
+ wrapper.b.b = 3
448
+ wrapper.c.a.b = 4
449
+ wrapper.c.a.c = 5
450
+ wrapper.c.a.d = 6
451
+
452
+ wrapper.min_stages # => 1
453
+ wrapper.b.min_stages # => 1
454
+ wrapper.c.min_stages # => 2
455
+ ```
456
+
457
+ ## Dashboard Class Usage
458
+ It is used like a two-dimensional array representing a table.
459
+
460
+ ### Add matrix table
461
+ ```ruby
462
+ dashboard = Deep::Hash::Struct::Dashboard.new
463
+ dashboard.add_table(matrix: true, side_header: "sh") do |t|
464
+ t.add_header do |h|
465
+ h.a = "h1"
466
+ h[:b] = "h2"
467
+ h.add :c, "h3"
468
+ end
469
+
470
+ t.add_side do |s|
471
+ s.a = "s1"
472
+ s[:b] = "s2"
473
+ s.add :c, "s3"
474
+ end
475
+
476
+ t.add_body do |row|
477
+ row.a.a = 11
478
+ row.a[:b] = 12
479
+ row[:a][:c] = 13
480
+ row[:b].a = 14
481
+ row.b.add :b, 15
482
+ row.b.c = 16
483
+ row.c.a = 17
484
+ row.c.b = 18
485
+ row.c.c = 19
486
+ end
487
+ end
488
+
489
+ dashboard.tables # => [#<Table matrix=true>]
490
+
491
+ table = "<table>\n"
492
+ dashboard.tables[0].each do |rows|
493
+ table << " <tr>\n"
494
+ rows.each do |row|
495
+ if row.header? || row.side?
496
+ table << " <th>#{row.name}</th>\n"
497
+ else
498
+ table << " <td>#{row.value}</td>\n"
499
+ end
500
+ end
501
+ table << " </tr>\n"
502
+ end
503
+ table << "</table>\n"
504
+
505
+ puts table
506
+ # => <table>
507
+ # => <tr>
508
+ # => <th>sh</th>
509
+ # => <th>h1</th>
510
+ # => <th>h2</th>
511
+ # => <th>h3</th>
512
+ # => </tr>
513
+ # => <tr>
514
+ # => <th>s1</th>
515
+ # => <td>11</td>
516
+ # => <td>14</td>
517
+ # => <td>17</td>
518
+ # => </tr>
519
+ # => <tr>
520
+ # => <th>s2</th>
521
+ # => <td>12</td>
522
+ # => <td>15</td>
523
+ # => <td>18</td>
524
+ # => </tr>
525
+ # => <tr>
526
+ # => <th>s3</th>
527
+ # => <td>13</td>
528
+ # => <td>16</td>
529
+ # => <td>19</td>
530
+ # => </tr>
531
+ # => </table>
532
+ ```
533
+
534
+ ### Add segment table
535
+ ```ruby
536
+ dashboard = Deep::Hash::Struct::Dashboard.new
537
+ dashboard.add_table do |t|
538
+ t.add_header do |h|
539
+ h.a = "h1"
540
+ h[:b] = "h2"
541
+ h.add :c, "h3"
542
+ end
543
+
544
+ t.add_body do |row|
545
+ row.a = 11
546
+ row.b = 12
547
+ row.c = 13
548
+ end
549
+
550
+ t.add_body do |row|
551
+ row.c = 16
552
+ row.b = 15
553
+ row.a = 14
554
+ end
555
+
556
+ t.add_body do |row|
557
+ row.c = 19
558
+ row.a = 17
559
+ row.b = 18
560
+ end
561
+ end
562
+
563
+ dashboard.tables # => [#<Table matrix=false>]
564
+
565
+ table = "<table>\n"
566
+ dashboard.tables[0].each do |rows|
567
+ table << " <tr>\n"
568
+ rows.each do |row|
569
+ if row.header?
570
+ table << " <th>#{row.name}</th>\n"
571
+ else
572
+ table << " <td>#{row.value}</td>\n"
573
+ end
574
+ end
575
+ table << " </tr>\n"
576
+ end
577
+ table << "</table>\n"
578
+
579
+ puts table
580
+ # => <table>
581
+ # => <tr>
582
+ # => <th>h1</th>
583
+ # => <th>h2</th>
584
+ # => <th>h3</th>
585
+ # => </tr>
586
+ # => <tr>
587
+ # => <td>11</td>
588
+ # => <td>12</td>
589
+ # => <td>13</td>
590
+ # => </tr>
591
+ # => <tr>
592
+ # => <td>14</td>
593
+ # => <td>15</td>
594
+ # => <td>16</td>
595
+ # => </tr>
596
+ # => <tr>
597
+ # => <td>17</td>
598
+ # => <td>18</td>
599
+ # => <td>19</td>
600
+ # => </tr>
601
+ # => </table>
602
+ ```
603
+
604
+ ### Unset value to matrix table
605
+ ```ruby
606
+ dashboard = Deep::Hash::Struct::Dashboard.new
607
+ dashboard.add_table(matrix: true) do |t|
608
+ t.add_header do |h|
609
+ h.a = "h1"
610
+ h[:b] = "h2"
611
+ h.add :c, "h3"
612
+ end
613
+
614
+ t.add_side do |s|
615
+ s.a = "s1"
616
+ s[:b] = "s2"
617
+ s.add :c, "s3"
618
+ end
619
+
620
+ t.add_body do |row|
621
+ row.a.b = 2
622
+ row.a.c = 3
623
+ row.b.a = 4
624
+ row.b.c = 6
625
+ row.c.a = 7
626
+ row.c.b = 8
627
+ end
628
+ end
629
+
630
+ dashboard.tables # => [#<Table matrix=true>]
631
+
632
+ table = "<table>\n"
633
+ dashboard.tables[0].each do |rows|
634
+ table << " <tr>\n"
635
+ rows.each do |row|
636
+ if row.header? || row.side?
637
+ table << " <th>#{row.name}</th>\n"
638
+ else
639
+ table << " <td>#{row.value}</td>\n"
640
+ end
641
+ end
642
+ table << " </tr>\n"
643
+ end
644
+ table << "</table>\n"
645
+
646
+ puts table
647
+ # => <table>
648
+ # => <tr>
649
+ # => <th></th>
650
+ # => <th>h1</th>
651
+ # => <th>h2</th>
652
+ # => <th>h3</th>
653
+ # => </tr>
654
+ # => <tr>
655
+ # => <th>s1</th>
656
+ # => <td></td>
657
+ # => <td>4</td>
658
+ # => <td>7</td>
659
+ # => </tr>
660
+ # => <tr>
661
+ # => <th>s2</th>
662
+ # => <td>2</td>
663
+ # => <td></td>
664
+ # => <td>8</td>
665
+ # => </tr>
666
+ # => <tr>
667
+ # => <th>s3</th>
668
+ # => <td>3</td>
669
+ # => <td>6</td>
670
+ # => <td></td>
671
+ # => </tr>
672
+ # =></table>
673
+ ```
674
+ ### Unset value to segment table
675
+ ```ruby
676
+ dashboard = Deep::Hash::Struct::Dashboard.new
677
+ dashboard.add_table do |t|
678
+ t.add_header do |h|
679
+ h.a = "h1"
680
+ h.b = "h2"
681
+ h.c = "h3"
682
+ end
683
+
684
+ t.add_body do |row|
685
+ row.b = 2
686
+ row.c = 3
687
+ end
688
+
689
+ t.add_body do |row|
690
+ row.a = 4
691
+ row.c = 6
692
+ end
693
+
694
+ t.add_body do |row|
695
+ row.a = 7
696
+ row.b = 8
697
+ end
698
+ end
699
+
700
+ dashboard.tables # => [#<Table matrix=false>]
701
+
702
+ table = "<table>\n"
703
+ dashboard.tables[0].each do |rows|
704
+ table << " <tr>\n"
705
+ rows.each do |row|
706
+ if row.header?
707
+ table << " <th>#{row.name}</th>\n"
708
+ else
709
+ table << " <td>#{row.value}</td>\n"
710
+ end
711
+ end
712
+ table << " </tr>\n"
713
+ end
714
+ table << "</table>\n"
715
+
716
+ puts table
717
+ # => <table>
718
+ # => <tr>
719
+ # => <th>h1</th>
720
+ # => <th>h2</th>
721
+ # => <th>h3</th>
722
+ # => </tr>
723
+ # => <tr>
724
+ # => <td></td>
725
+ # => <td>2</td>
726
+ # => <td>3</td>
727
+ # => </tr>
728
+ # => <tr>
729
+ # => <td>4</td>
730
+ # => <td></td>
731
+ # => <td>6</td>
732
+ # => </tr>
733
+ # => <tr>
734
+ # => <td>7</td>
735
+ # => <td>8</td>
736
+ # => <td></td>
737
+ # => </tr>
738
+ # => </table>
739
+ ```
740
+
741
+ ### Default to matrix table
742
+ ```ruby
743
+ dashboard = Deep::Hash::Struct::Dashboard.new
744
+ dashboard.add_table(matrix: true, default: 0) do |t|
745
+ t.add_header do |h|
746
+ h.a = "h1"
747
+ h.b = "h2"
748
+ h.c = "h3"
749
+ end
750
+
751
+ t.add_side do |s|
752
+ s.a = "s1"
753
+ s.b = "s2"
754
+ s.c = "s3"
755
+ end
756
+
757
+ t.add_body do |row|
758
+ row.a.b = 2
759
+ row.a.c = 3
760
+ row.b.a = 4
761
+ row.b.c = 6
762
+ row.c.a = 7
763
+ row.c.b = 8
764
+ end
765
+ end
766
+
767
+ dashboard.tables # => [#<Table matrix=true>]
768
+
769
+ table = "<table>\n"
770
+ dashboard.tables[0].each do |rows|
771
+ table << " <tr>\n"
772
+ rows.each do |row|
773
+ if row.header? || row.side?
774
+ table << " <th>#{row.name}</th>\n"
775
+ else
776
+ table << " <td>#{row.value}</td>\n"
777
+ end
778
+ end
779
+ table << " </tr>\n"
780
+ end
781
+ table << "</table>\n"
782
+
783
+ puts table
784
+ # => <table>
785
+ # => <tr>
786
+ # => <th></th>
787
+ # => <th>h1</th>
788
+ # => <th>h2</th>
789
+ # => <th>h3</th>
790
+ # => </tr>
791
+ # => <tr>
792
+ # => <th>s1</th>
793
+ # => <td>0</td>
794
+ # => <td>4</td>
795
+ # => <td>7</td>
796
+ # => </tr>
797
+ # => <tr>
798
+ # => <th>s2</th>
799
+ # => <td>2</td>
800
+ # => <td>0</td>
801
+ # => <td>8</td>
802
+ # => </tr>
803
+ # => <tr>
804
+ # => <th>s3</th>
805
+ # => <td>3</td>
806
+ # => <td>6</td>
807
+ # => <td>0</td>
808
+ # => </tr>
809
+ # => </table>
810
+ ```
811
+
812
+ ### Default to segment table
813
+ ```ruby
814
+ dashboard = Deep::Hash::Struct::Dashboard.new
815
+ dashboard.add_table(default: 0) do |t|
816
+ t.add_header do |h|
817
+ h.a = "h1"
818
+ h.b = "h2"
819
+ h.c = "h3"
820
+ end
821
+
822
+ t.add_body do |row|
823
+ row.b = 2
824
+ row.c = 3
825
+ end
826
+
827
+ t.add_body do |row|
828
+ row.a = 4
829
+ row.c = 6
830
+ end
831
+
832
+ t.add_body do |row|
833
+ row.a = 7
834
+ row.b = 8
835
+ end
836
+ end
837
+
838
+ dashboard.tables # => [#<Table matrix=false>]
839
+
840
+ table = "<table>\n"
841
+ dashboard.tables[0].each do |rows|
842
+ table << " <tr>\n"
843
+ rows.each do |row|
844
+ if row.header?
845
+ table << " <th>#{row.name}</th>\n"
846
+ else
847
+ table << " <td>#{row.value}</td>\n"
848
+ end
849
+ end
850
+ table << " </tr>\n"
851
+ end
852
+ table << "</table>\n"
853
+
854
+ puts table
855
+ # => <table>
856
+ # => <tr>
857
+ # => <th>h1</th>
858
+ # => <th>h2</th>
859
+ # => <th>h3</th>
860
+ # => </tr>
861
+ # => <tr>
862
+ # => <td>0</td>
863
+ # => <td>2</td>
864
+ # => <td>3</td>
865
+ # => </tr>
866
+ # => <tr>
867
+ # => <td>4</td>
868
+ # => <td>0</td>
869
+ # => <td>6</td>
870
+ # => </tr>
871
+ # => <tr>
872
+ # => <td>7</td>
873
+ # => <td>8</td>
874
+ # => <td>0</td>
875
+ # => </tr>
876
+ # => </table>
877
+ ```
878
+
33
879
  ## Contributing
34
880
 
35
881
  Bug reports and pull requests are welcome on GitHub at https://github.com/etiopiamokamame/deep-hash-struct. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.