Module: JsonCsv::JsonToCsv::ClassMethods
- Defined in:
- lib/json_csv/json_to_csv.rb
Constant Summary collapse
- DEFAULT_HEADER_SORT_COMPARATOR =
lambda do |header1, header2| # Ensure correct alphabetical sorting AND numeric sorting via zero-padding of numbers header1_with_zero_padding = header1.gsub(/(?<=\[)\d+(?=\])/) { |capture| capture.to_i.to_s.rjust(5, '0') } header2_with_zero_padding = header2.gsub(/(?<=\[)\d+(?=\])/) { |capture| capture.to_i.to_s.rjust(5, '0') } header1_with_zero_padding <=> header2_with_zero_padding end
Instance Method Summary collapse
-
#create_csv_for_json_records(csv_outfile_path, header_sort_comparator = DEFAULT_HEADER_SORT_COMPARATOR) ⇒ Object
Example usage: create_csv_for_json_records(‘/path/to/file.csv’) do |csv_builder| json_docs.each do |json_doc| csv_builder.add(json_hash) end end.
- #default_header_comparison(header1, header2) ⇒ Object
-
#flatten_hash(obj, parent_path = '', flat_hash_to_build = {}) ⇒ Object
This method calls itself recursively while flattening a hash, and during this sequence of calls the obj param may either be a hash or an array.
-
#json_hash_to_flat_csv_row_hash(json_hash) ⇒ Object
Converts the given json_hash into a flat csv hash, converting all values to strings (because CSVs are dumb and don’t store info about data types) Set first_index to 1 if you want the first element in an array to.
- #key_contains_unallowed_characters?(key) ⇒ Boolean
Instance Method Details
#create_csv_for_json_records(csv_outfile_path, header_sort_comparator = DEFAULT_HEADER_SORT_COMPARATOR) ⇒ Object
Example usage: create_csv_for_json_records(‘/path/to/file.csv’) do |csv_builder|
json_docs.each do |json_doc|
csv_builder.add(json_hash)
end
end
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 |
# File 'lib/json_csv/json_to_csv.rb', line 29 def create_csv_for_json_records(csv_outfile_path, header_sort_comparator = DEFAULT_HEADER_SORT_COMPARATOR) csv_temp_outfile_path = csv_outfile_path + '.temp' begin # Step 1: Build CSV with unsorted headers in temp file csv_headers = JsonCsv::CsvBuilder.create_csv_without_headers(csv_temp_outfile_path, 'wb') do |csv_builder| yield csv_builder end # Step 2: Sort CSV columns by header, based on column_header_comparator original_to_sorted_index_map = JsonCsv::CsvBuilder.original_header_indexes_to_sorted_indexes(csv_headers, header_sort_comparator) CSV.open(csv_outfile_path, 'wb') do |final_csv| # Open temporary CSV for reading CSV.open(csv_temp_outfile_path, 'rb') do |temp_csv| # write out ordered header row reordered_header_row = [] csv_headers.each_with_index do |header, index| reordered_header_row[original_to_sorted_index_map[index]] = header end final_csv << reordered_header_row temp_csv.each do |temp_csv_row| reordered_temp_csv_row = [] # write out ordered data row temp_csv_row.each_with_index do |cell_value, index| reordered_temp_csv_row[original_to_sorted_index_map[index]] = cell_value end final_csv << reordered_temp_csv_row end end end ensure # Always delete the temporary CSV FileUtils.rm_f(csv_temp_outfile_path) end end |
#default_header_comparison(header1, header2) ⇒ Object
19 20 21 |
# File 'lib/json_csv/json_to_csv.rb', line 19 def default_header_comparison(header1, header2) DEFAULT_HEADER_SORT_COMPARATOR.call(header1, header2) end |
#flatten_hash(obj, parent_path = '', flat_hash_to_build = {}) ⇒ Object
This method calls itself recursively while flattening a hash, and during this sequence of calls the obj param may either be a hash or an array.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/json_csv/json_to_csv.rb', line 81 def flatten_hash(obj, parent_path = '', flat_hash_to_build = {}) if obj.is_a?(Hash) obj.each do |key, val| if key_contains_unallowed_characters?(key) raise ArgumentError, 'Cannot deal with hash keys that contain "[" or "]" or "." because these characters have special meanings in CSV headers.' end path = parent_path + (parent_path.empty? ? '' : '.') + key flatten_hash(val, path, flat_hash_to_build) end elsif obj.is_a?(Array) obj.each_with_index do |el, index| path = parent_path + "[#{index}]" flatten_hash(el, path, flat_hash_to_build) end else flat_hash_to_build[parent_path] = obj unless obj.nil? || obj == '' # ignore nil or empty string values end flat_hash_to_build end |
#json_hash_to_flat_csv_row_hash(json_hash) ⇒ Object
Converts the given json_hash into a flat csv hash, converting all values to strings (because CSVs are dumb and don’t store info about data types) Set first_index to 1 if you want the first element in an array to
72 73 74 75 76 77 |
# File 'lib/json_csv/json_to_csv.rb', line 72 def json_hash_to_flat_csv_row_hash(json_hash) flat = flatten_hash(json_hash) # Convert values to strings because in the CSV file, all values are strings flat.each { |key, val| flat[key] = val.nil? ? '' : val.to_s } flat end |
#key_contains_unallowed_characters?(key) ⇒ Boolean
102 103 104 105 |
# File 'lib/json_csv/json_to_csv.rb', line 102 def key_contains_unallowed_characters?(key) return true if key.index('[') || key.index(']') || key.index('.') false end |