Class: VFCSV::Row
Overview
A CSV::Row-compatible class representing a single row of CSV data. Supports both header-based (Hash-like) and index-based (Array-like) access.
Instance Attribute Summary collapse
-
#row ⇒ Object
readonly
Returns the value of attribute row.
Instance Method Summary collapse
-
#<<(arg) ⇒ self
Append a field.
-
#==(other) ⇒ Boolean
Compare with another row.
-
#[](header_or_index, minimum_index = 0) ⇒ String?
(also: #field)
Access a field by header name or index.
-
#[]=(header_or_index, value) ⇒ Object
Set a field by header name or index.
-
#delete(header_or_index) ⇒ Array?
Delete a field by header or index.
-
#delete_if {|header, value| ... } ⇒ self
Delete fields matching a condition.
-
#dig(index_or_header, *identifiers) ⇒ Object
Dig into nested data.
-
#each {|header, value| ... } ⇒ Enumerator
(also: #each_pair)
Iterate over header/value pairs.
-
#empty? ⇒ Boolean
Check if row is empty.
-
#fetch(header_or_index, *args) { ... } ⇒ Object
Fetch a field with optional default.
-
#field?(value) ⇒ Boolean
(also: #include?, #member?)
Check if a value exists in the fields.
-
#field_row? ⇒ Boolean
Check if this is a field (data) row.
-
#fields ⇒ Array
(also: #values)
Get field values.
-
#header?(header) ⇒ Boolean
(also: #has_key?, #key?)
Check if a header exists.
-
#header_row? ⇒ Boolean
Check if this is a header row.
-
#headers ⇒ Array
Get headers.
-
#index(header, minimum_index = 0) ⇒ Integer?
Find index of a header or value.
-
#initialize(headers, fields, header_row: false) ⇒ Row
constructor
Create a new Row.
-
#inspect ⇒ String
Inspection string.
-
#push(header, value) ⇒ self
Push a header and value.
-
#size ⇒ Integer
(also: #length)
Get number of fields.
-
#to_a ⇒ Array<Array>
Convert to array of [header, value] pairs.
-
#to_ary ⇒ Array
Allow implicit conversion to array (for splat operations).
-
#to_csv(**options) ⇒ String
(also: #to_s)
Convert to CSV string.
-
#to_h ⇒ Hash
(also: #to_hash)
Convert to hash.
-
#values_at(*indices_or_headers) ⇒ Array
Get values at specified indices or headers.
Constructor Details
#initialize(headers, fields, header_row: false) ⇒ Row
Create a new Row
15 16 17 18 |
# File 'lib/vfcsv/row.rb', line 15 def initialize(headers, fields, header_row: false) @row = headers.zip(fields).map { |pair| pair } @header_row = header_row end |
Instance Attribute Details
#row ⇒ Object (readonly)
Returns the value of attribute row.
9 10 11 |
# File 'lib/vfcsv/row.rb', line 9 def row @row end |
Instance Method Details
#<<(arg) ⇒ self
Append a field
76 77 78 79 80 81 82 83 |
# File 'lib/vfcsv/row.rb', line 76 def <<(arg) if arg.is_a?(Array) && arg.size == 2 @row << arg.dup else @row << [nil, arg] end self end |
#==(other) ⇒ Boolean
Compare with another row
232 233 234 235 |
# File 'lib/vfcsv/row.rb', line 232 def ==(other) return false unless other.is_a?(Row) @row == other.row end |
#[](header_or_index, minimum_index = 0) ⇒ String? Also known as: field
Access a field by header name or index
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/vfcsv/row.rb', line 37 def [](header_or_index, minimum_index = 0) if header_or_index.is_a?(Integer) pair = @row[header_or_index] pair&.last else # Search by header name @row.each_with_index do |(header, value), index| next if index < minimum_index return value if header == header_or_index end nil end end |
#[]=(header_or_index, value) ⇒ Object
Set a field by header name or index
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/vfcsv/row.rb', line 55 def []=(header_or_index, value) if header_or_index.is_a?(Integer) if @row[header_or_index] @row[header_or_index][1] = value end else @row.each do |pair| if pair[0] == header_or_index pair[1] = value return value end end # Header not found, add new pair @row << [header_or_index, value] end value end |
#delete(header_or_index) ⇒ Array?
Delete a field by header or index
97 98 99 100 101 102 103 104 |
# File 'lib/vfcsv/row.rb', line 97 def delete(header_or_index) if header_or_index.is_a?(Integer) @row.delete_at(header_or_index) else index = @row.index { |pair| pair[0] == header_or_index } index ? @row.delete_at(index) : nil end end |
#delete_if {|header, value| ... } ⇒ self
Delete fields matching a condition
109 110 111 112 |
# File 'lib/vfcsv/row.rb', line 109 def delete_if(&block) @row.delete_if { |pair| block.call(*pair) } self end |
#dig(index_or_header, *identifiers) ⇒ Object
Dig into nested data
198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/vfcsv/row.rb', line 198 def dig(index_or_header, *identifiers) value = self[index_or_header] return nil if value.nil? return value if identifiers.empty? if value.respond_to?(:dig) value.dig(*identifiers) else nil end end |
#each {|header, value| ... } ⇒ Enumerator Also known as: each_pair
Iterate over header/value pairs
117 118 119 120 121 |
# File 'lib/vfcsv/row.rb', line 117 def each(&block) return to_enum(__method__) unless block_given? @row.each { |pair| block.call(*pair) } self end |
#empty? ⇒ Boolean
Check if row is empty
126 127 128 |
# File 'lib/vfcsv/row.rb', line 126 def empty? @row.empty? end |
#fetch(header_or_index, *args) { ... } ⇒ Object
Fetch a field with optional default
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/vfcsv/row.rb', line 142 def fetch(header_or_index, *args, &block) value = self[header_or_index] return value unless value.nil? # Check if header actually exists with nil value found = if header_or_index.is_a?(Integer) header_or_index >= 0 && header_or_index < @row.size else @row.any? { |pair| pair[0] == header_or_index } end return value if found if block_given? block.call(header_or_index) elsif args.size > 0 args[0] else raise KeyError, "key not found: #{header_or_index.inspect}" end end |
#field?(value) ⇒ Boolean Also known as: include?, member?
Check if a value exists in the fields
167 168 169 |
# File 'lib/vfcsv/row.rb', line 167 def field?(value) fields.include?(value) end |
#field_row? ⇒ Boolean
Check if this is a field (data) row
225 226 227 |
# File 'lib/vfcsv/row.rb', line 225 def field_row? !@header_row end |
#fields ⇒ Array Also known as: values
Get field values
28 29 30 |
# File 'lib/vfcsv/row.rb', line 28 def fields @row.map(&:last) end |
#header?(header) ⇒ Boolean Also known as: has_key?, key?
Check if a header exists
176 177 178 |
# File 'lib/vfcsv/row.rb', line 176 def header?(header) headers.include?(header) end |
#header_row? ⇒ Boolean
Check if this is a header row
219 220 221 |
# File 'lib/vfcsv/row.rb', line 219 def header_row? @header_row end |
#headers ⇒ Array
Get headers
22 23 24 |
# File 'lib/vfcsv/row.rb', line 22 def headers @row.map(&:first) end |
#index(header, minimum_index = 0) ⇒ Integer?
Find index of a header or value
186 187 188 189 190 191 192 |
# File 'lib/vfcsv/row.rb', line 186 def index(header, minimum_index = 0) @row.each_with_index do |(h, _v), i| next if i < minimum_index return i if h == header end nil end |
#inspect ⇒ String
Inspection string
281 282 283 |
# File 'lib/vfcsv/row.rb', line 281 def inspect "#<#{self.class} #{to_h.inspect}>" end |
#push(header, value) ⇒ self
Push a header and value
89 90 91 92 |
# File 'lib/vfcsv/row.rb', line 89 def push(header, value) @row << [header, value] self end |
#size ⇒ Integer Also known as: length
Get number of fields
132 133 134 |
# File 'lib/vfcsv/row.rb', line 132 def size @row.size end |
#to_a ⇒ Array<Array>
Convert to array of [header, value] pairs
248 249 250 |
# File 'lib/vfcsv/row.rb', line 248 def to_a @row.map(&:dup) end |
#to_ary ⇒ Array
Allow implicit conversion to array (for splat operations)
254 255 256 |
# File 'lib/vfcsv/row.rb', line 254 def to_ary fields end |
#to_csv(**options) ⇒ String Also known as: to_s
Convert to CSV string
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/vfcsv/row.rb', line 260 def to_csv(**) col_sep = [:col_sep] || "," quote_char = [:quote_char] || '"' row_sep = [:row_sep] row_sep = "\n" if row_sep.nil? || row_sep == :auto field_strings = fields.map do |field| field_str = field.to_s if needs_quoting?(field_str, col_sep, quote_char) quote_field(field_str, quote_char) else field_str end end field_strings.join(col_sep) + row_sep end |
#to_h ⇒ Hash Also known as: to_hash
Convert to hash
239 240 241 242 243 |
# File 'lib/vfcsv/row.rb', line 239 def to_h result = {} @row.each { |header, value| result[header] = value } result end |
#values_at(*indices_or_headers) ⇒ Array
Get values at specified indices or headers
213 214 215 |
# File 'lib/vfcsv/row.rb', line 213 def values_at(*indices_or_headers) indices_or_headers.map { |i| self[i] } end |