Class: CsvHuman::Columns

Inherits:
Object
  • Object
show all
Defined in:
lib/csvhuman/column.rb

Class Method Summary collapse

Class Method Details

.build(values, header_converter) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/csvhuman/column.rb', line 10

def self.build( values, header_converter )

  ## "clean" unify/normalize names
  keys = values.map do |value|
    if value
      if value.empty?
        nil
      else
        ## e.g. #ADM1 CODE                      => #adm1 +code
        ##      POPULATION F CHILDREN AFFECTED  => #population +affected +children +f
        tag_key = Tag.normalize( value )
        ## turn empty normalized tags (e.g. "stray" hashtag) into nil too

        if value.empty?
            nil
        else
            header_key =
            ##   todo/fix: pass in column index - why? why not?
            ##     pass in column index for all columns (or only tagged ones?) or both?
            ##   if header_converter.arity == 1  # straight converter
                   header_converter.call( tag_key )
            ##   else
            ##       header_converter.call( value, index )
            ##    end

            ## note:
            ##   return nil, "" or false to skip column
            if header_key.nil? || header_key.empty? || header_key == false   ## check again: skip empty "" columns
              nil
            else
              ##  note: return header_key (used for returned record/hash) AND tag_key (used for type conversion config)
              ## lets us fold more columns into one or splat single list/array columns into many
              [header_key,tag_key]
            end
        end
      end
    else  # keep (nil) as is
      nil
    end
  end


  counts = {}
  keys.each_with_index do |key,i|
     if key
       header_key = key[0]
       counts[header_key] ||= []
       counts[header_key] << i
     end
  end
  ## puts "counts:"
  ## pp counts


  ## create all unique tags  (used for type conversion)
  tags = {}
  keys.each do |key|
    if key
      tag_key = key[1]
      tags[tag_key] ||= Tag.parse( tag_key )  ## note: "reuse" tag for all columns if same tag key
    end
  end
  ## puts "tags:"
  ## pp tags


  cols = []
  keys.each do |key|
    if key
      header_key = key[0]
      tag_key    = key[1]

      count = counts[header_key]
      tag   = tags[tag_key]        ## note: "reuse" tag for all columns if same tag key

      if count.size > 1
        ## note: defaults to use "standard/default" tag key (as a string)
        cols << Column.new( header_key, tag, list: true )
      else
        cols << Column.new( header_key, tag )
      end
    else
      cols << Column.new
    end
  end

  cols
end