module JSON22d
Constants
- VERSION
Public Instance Methods
run(arr, config) { |h| ... }
click to toggle source
# File lib/json22d.rb, line 10 def run(arr, config) arr = arr.to_json unless arr.is_a?(String) arr = JSON.parse(arr) fill_blanks(arr, config, &(block_given? ? Proc.new : nil)) return Enumerator.new do |y| y << header(config) arr.each do |h| row(block_given? ? yield(h) : h, config).each { |r| y << r } end end end
Private Instance Methods
fill_blanks(values, config) { |v| ... }
click to toggle source
# File lib/json22d.rb, line 24 def fill_blanks(values, config) values = values.first if values.is_a?(Array) && values.size == 1 values = [values] unless values.is_a?(Array) subconfig = config.select { |c| c.is_a?(Hash) } subconfig.each do |name| key, value = name.first comment, key, no_n, shift, unshift = key.to_s. match(/^(#)?([^\[]+?)(\[\])?( SHIFT)?( UNSHIFT)?$/)&. captures if no_n max_n = values.reduce(0) do |acc, v| v = yield(v) if block_given? sub_hash = v&.[](key) if sub_hash.is_a?(Array) acc = sub_hash.count if acc < sub_hash.count elsif !sub_hash.nil? acc = 1 if acc < 1 end next acc end name.delete(name.keys.first) name["#{key}[#{max_n}]#{shift}#{unshift}"] = value end fill_blanks(values.map do |v| v = yield(v) if block_given? comment ? v : v&.[](key) end, value) end end
header(config)
click to toggle source
# File lib/json22d.rb, line 55 def header(config) return config.reduce([]) do |acc, name| if name.is_a?(Hash) key, value = name.first comment, key, closures, n, n2, shift, unshift = key.to_s. match(/^(#)?([^\[(\s]+)(\[(\d+)\]|\(([^\)]+)\))?( SHIFT)?( UNSHIFT)?$/)&. captures key, op = key.split(".") key = key.singularize if comment acc + header(value).map { |m| "#{key}.#{m}" } elsif n next acc + n.to_i.times.reduce([]) do |a, i| a + header(value).map do |m| if shift "#{key}[#{i}]#{m.match(/^[^(\[\s\.]+(.*)$/)&.captures&.first}" elsif unshift "#{m}[#{i}]" elsif op "#{key}.#{op}_#{m}" else "#{key}[#{i}].#{m}" end end end elsif closures.nil? || n2 next acc + header(value).map do |m| if shift "#{key}#{m.match(/^[^(\[\s\.]+(.*)$/)&.captures&.first}" elsif unshift "#{m}" elsif op "#{key}.#{op}_#{m}" else "#{key}.#{m}" end end else # "pos" is the column for determining i.e. offer position in a product next acc + (["pos"] + header(value)).map do |m| if shift "#{key}#{m.match(/^[^(\[\s\.]+(.*)$/)&.captures&.first}" elsif unshift "#{m}" elsif op "#{key}.#{op}_#{m}" else "#{key}.#{m}" end end end elsif name.is_a?(Array) _key, title = name next acc << title.to_s else name, *_ = name.to_s.match(/^([^(]+)(\(([^\)]+)\))?$/)&.captures name = name.match(/^([^+]+)/).captures.first next acc << name.to_s end end end
multiply(array, result = [[]])
click to toggle source
# File lib/json22d.rb, line 121 def multiply(array, result = [[]]) array = [array] unless array.is_a?(Array) array.each do |elem| if elem.is_a?(Array) result = elem.reduce([]) { |a, e| a + multiply(e, result.map(&:dup)) } else result = result.map { |r| r << elem } end end return result end
row(hash, config)
click to toggle source
# File lib/json22d.rb, line 117 def row(hash, config) multiply(slice(hash, config)) end
slice(hash, config)
click to toggle source
# File lib/json22d.rb, line 133 def slice(hash, config) return config.reduce([]) do |acc, name| if name.is_a?(Hash) key, value = name.first comment, key, closures, n, n2, _shift, _unshift = key.to_s. match(/^(#)?([^\[(\s]+)(\[(\d+)\]|\(([^\)]+)\))?( SHIFT)?( UNSHIFT)?$/)&. captures key, op = key.split(".") sub_hash = hash&.[](key) if comment acc + slice(hash, value) elsif n2 && sub_hash next acc << sub_hash. reduce([]) { |a, h| a + slice(h, value) }. join(n2) elsif n && (sub_hash || n.to_i == 0) next acc + n.to_i.times.map { |i| sub_hash[i] }. reduce([]) { |a, h| a + slice(h, value) } elsif sub_hash.is_a?(Array) # [i] is the "pos" column next acc << [slice({}, value)] if sub_hash.empty? next acc << sub_hash.map. with_index do |h, i| (closures.nil? ? [] : [i]) + slice(h, value) end.reduce(nil, &with_op(op)) else next acc + slice(sub_hash, value) end else if hash.nil? next acc << hash else name, _title = name if name.is_a?(Array) name, closures, n = name.to_s. match(/^([^(]+)(\(([^\)]+)\))?$/)&.captures sub_array = hash[name] if sub_array.is_a?(Array) sub_array = sub_array.map(&method(:sprintf)) else sub_array = sprintf(sub_array) end if name.include?("+") next acc << name.split("+").map { |k| hash[k] }.compact.join(" ") elsif name.include?("|") next acc << hash[name.split("|").detect { |k| hash[k] }] elsif n && sub_array.is_a?(Array) next acc << sub_array.join(n) else next acc << sub_array end end end end end
sprintf(value)
click to toggle source
# File lib/json22d.rb, line 216 def sprintf(value) if !value.respond_to?(:strftime) && value !~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/ return value end value = Time.parse(value) if !value.respond_to?(:strftime) return value.strftime("%Y-%m-%d %H:%M:%S %Z") end
with_op(op)
click to toggle source
# File lib/json22d.rb, line 188 def with_op(op) if op case op when "min" ->(a, e) do e = e.first if e.is_a?(Array) ef = e.to_f af = a&.to_f (af || ef) > ef ? e : (a || e) end when "max" ->(a, e) do e = e.first if e.is_a?(Array) ef = e.to_f af = a&.to_f (af || 0) < ef ? e : a end when "first" ->(a, e) do e = e.first if e.is_a?(Array) a || e end end else return ->(a, e) { (a || []) << e } end end