Module: SmarterCSV::HeaderTransformations
- Included in:
- Reader
- Defined in:
- lib/smarter_csv/header_transformations.rb
Instance Method Summary collapse
- #disambiguate_headers(headers, options) ⇒ Object
-
#header_transformations(header_array, options) ⇒ Object
transform the headers that were in the file:.
-
#remap_headers(headers, options) ⇒ Object
do some key mapping on the keys in the file header if you want to completely delete a key, then map it to nil or to ''.
Instance Method Details
#disambiguate_headers(headers, options) ⇒ Object
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 |
# File 'lib/smarter_csv/header_transformations.rb', line 28 def disambiguate_headers(headers, ) counts = Hash.new(0) prefix = [:missing_header_prefix] || 'column_' # Pre-collect non-blank header names so auto-generated names can avoid collisions. used = headers.reject { |h| blank?(h) } headers.each_with_index.map do |header, idx| if blank?(header) # Use absolute 1-based column position, consistent with how extra data columns # beyond the header count are named. If the positional name collides with an # existing header, append underscores until a free name is found — this avoids # stealing the positional name from any subsequent blank header. candidate = "#{prefix}#{idx + 1}" suffix = '' while used.include?(candidate) suffix += '_' candidate = "#{prefix}#{idx + 1}#{suffix}" end used << candidate candidate else counts[header] += 1 counts[header] > 1 ? "#{header}#{[:duplicate_header_suffix]}#{counts[header]}" : header end end end |
#header_transformations(header_array, options) ⇒ Object
transform the headers that were in the file:
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/smarter_csv/header_transformations.rb', line 6 def header_transformations(header_array, ) header_array.map!{|x| x.gsub(%r/#{[:quote_char]}/, '')} header_array.map!{|x| x.strip} if [:strip_whitespace] unless [:keep_original_headers] # Normalize whitespace-only headers to "" before gsub so they are treated as # blank/missing by disambiguate_headers rather than converted to "_". header_array.map!{|x| blank?(x) ? '' : x} unless [:strip_whitespace] header_array.map!{|x| x.gsub(/\s+|-+/, '_')} header_array.map!{|x| x.downcase} if [:downcase_header] end # detect duplicate headers and disambiguate header_array = disambiguate_headers(header_array, ) if [:duplicate_header_suffix] # symbolize headers header_array = header_array.map{|x| x.to_sym } unless [:strings_as_keys] || [:keep_original_headers] # doesn't make sense to re-map when we have user_provided_headers header_array = remap_headers(header_array, ) if [:key_mapping] header_array end |
#remap_headers(headers, options) ⇒ Object
do some key mapping on the keys in the file header if you want to completely delete a key, then map it to nil or to ''
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 |
# File 'lib/smarter_csv/header_transformations.rb', line 56 def remap_headers(headers, ) key_mapping = [:key_mapping] if key_mapping.empty? || !key_mapping.is_a?(Hash) || key_mapping.keys.empty? raise(SmarterCSV::IncorrectOption, "ERROR: incorrect format for key_mapping! Expecting hash with from -> to mappings") end key_mapping = [:key_mapping] # if silence_missing_keys are not set, raise error if missing header missing_keys = key_mapping.keys - headers # if the user passes a list of speciffic mapped keys that are optional missing_keys -= [:silence_missing_keys] if [:silence_missing_keys].is_a?(Array) unless missing_keys.empty? || [:silence_missing_keys] == true raise SmarterCSV::KeyMappingError, "ERROR: can not map headers: #{missing_keys.join(', ')}" end headers.map! do |header| if key_mapping.has_key?(header) key_mapping[header].nil? ? nil : key_mapping[header] elsif [:remove_unmapped_keys] nil else header end end headers end |