Permalink
Browse files

implemented feature for limiting convertion of numeric values (issue #24

)
  • Loading branch information...
tilo committed Jan 13, 2014
1 parent c5cfe1b commit 03139def0ee12f82c8f2097ec90f9525bc6b71e4
View
@@ -148,6 +148,7 @@ The options and the block are optional.
| :remove_values_matching | nil | removes key/value pairs if value matches given regular expressions. e.g.: |
| | | /^\$0\.0+$/ to match $0.00 , or /^#VALUE!$/ to match errors in Excel spreadsheets |
| :convert_values_to_numeric | true | converts strings containing Integers or Floats to the appropriate class |
+ | | | also accepts either {:except => [:key1,:key2]} or {:only => :key3} |
| :remove_empty_hashes | true | remove / ignore any hashes which don't have any key/value pairs |
| :user_provided_headers | nil | *careful with that axe!* |
| | | user provided Array of header strings or symbols, to define |
@@ -227,6 +228,10 @@ Or install it yourself as:
## Changes
+#### 1.0.16 (2014-01-13)
+ * :convert_values_to_numeric option can now be qualified with :except or :only (thanks to Hugo Lepetit)
+ * removed deprecated `process_csv` method
+
#### 1.0.15 (2013-12-07)
* new option:
* :remove_unmapped_keys to completely ignore columns which were not mapped with :key_mapping (thanks to Dave Sanders)
@@ -328,6 +333,7 @@ And a special thanks to those who contributed pull requests:
* [Marcos G. Zimmermann](https://github.com/marcosgz)
* [Jordan Running](https://github.com/jrunning)
* [Dave Sanders](https://github.com/DaveSanders)
+ * [Hugo Lepetit](https://github.com/giglemad)
## Contributing
@@ -1,7 +1,8 @@
module SmarterCSV
- class HeaderSizeMismatch < Exception
- end
+ class HeaderSizeMismatch < Exception; end
+
+ class IncorrectOption < Exception; end
def SmarterCSV.process(input, options={}, &block) # first parameter: filename or input object with readline method
default_options = {:col_sep => ',' , :row_sep => $/ , :quote_char => '"', :force_simple_split => false , :verbose => false ,
@@ -103,6 +104,10 @@ def SmarterCSV.process(input, options={}, &block) # first parameter: filename
hash.delete_if{|k,v| v =~ options[:remove_values_matching]} if options[:remove_values_matching]
if options[:convert_values_to_numeric]
hash.each do |k,v|
+ # deal with the :only / :except options to :convert_values_to_numeric
+ next if SmarterCSV.only_or_except_limit_execution( options, :convert_values_to_numeric , k )
+
+ # convert if it's a numeric value:
case v
when /^[+-]?\d+\.\d+$/
hash[k] = v.to_f
@@ -128,11 +133,9 @@ def SmarterCSV.process(input, options={}, &block) # first parameter: filename
else
# the last chunk may contain partial data, which also needs to be returned (BUG / ISSUE-18)
-
end
-
# while a chunk is being filled up we don't need to do anything else here
else # no chunk handling
@@ -164,9 +167,23 @@ def SmarterCSV.process(input, options={}, &block) # first parameter: filename
end
end
- def SmarterCSV.process_csv(*args)
- warn "[DEPRECATION] `process_csv` is deprecated. Please use `process` instead."
- SmarterCSV.process(*args)
+# def SmarterCSV.process_csv(*args)
+# warn "[DEPRECATION] `process_csv` is deprecated. Please use `process` instead."
+# SmarterCSV.process(*args)
+# end
+
+ private
+ # acts as a road-block to limit processing when iterating over all k/v pairs of a CSV-hash:
+
+ def self.only_or_except_limit_execution( options, option_name, key )
+ if options[option_name].is_a?(Hash)
+ if options[option_name].has_key?( :except )
+ return true if Array( options[ option_name ][:except] ).include?(key)
+ elsif options[ option_name ].has_key?(:only)
+ return true unless Array( options[ option_name ][:only] ).include?(key)
+ end
+ end
+ return false
end
end
@@ -1,3 +1,3 @@
module SmarterCSV
- VERSION = "1.0.15"
+ VERSION = "1.0.16"
end
@@ -0,0 +1,5 @@
+First Name,Last Name,Reference, Wealth
+Dan,McAllister,0123,3.5
+,,,,,
+Miles,O'Brian,2345,3
+Nancy,Homes,2345,01
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+fixture_path = 'spec/fixtures'
+
+describe 'numeric conversion of values' do
+ it 'occurs by default' do
+ options = {}
+ data = SmarterCSV.process("#{fixture_path}/numeric.csv", options)
+ data.size.should == 3
+
+ # all the keys should be symbols
+ data.each do |hash|
+ hash[:wealth].should be_a_kind_of(Numeric) unless hash[:wealth].nil?
+ hash[:reference].should be_a_kind_of(Numeric) unless hash[:reference].nil?
+ end
+ end
+
+ it 'can be prevented for all values' do
+ options = { convert_values_to_numeric: false }
+ data = SmarterCSV.process("#{fixture_path}/numeric.csv", options)
+
+ data.each do |hash|
+ hash[:wealth].should be_a_kind_of(String) unless hash[:wealth].nil?
+ hash[:reference].should be_a_kind_of(String) unless hash[:reference].nil?
+ end
+ end
+
+ it 'can be prevented for some keys' do
+ options = { convert_values_to_numeric: { except: :reference }}
+ data = SmarterCSV.process("#{fixture_path}/numeric.csv", options)
+
+ data.each do |hash|
+ hash[:wealth].should be_a_kind_of(Numeric) unless hash[:wealth].nil?
+ hash[:reference].should be_a_kind_of(String) unless hash[:reference].nil?
+ end
+ end
+
+ it 'can occur only for some keys' do
+ options = { convert_values_to_numeric: { only: :wealth }}
+ data = SmarterCSV.process("#{fixture_path}/numeric.csv", options)
+
+ data.each do |hash|
+ hash[:wealth].should be_a_kind_of(Numeric) unless hash[:wealth].nil?
+ hash[:reference].should be_a_kind_of(String) unless hash[:reference].nil?
+ end
+ end
+end
+

0 comments on commit 03139de

Please sign in to comment.