Class: CSV::Row
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Forwardable
|
|
Instance Chain:
self,
Enumerable
|
|
Inherits: | Object |
Defined in: | lib/csv/row.rb |
Overview
A Row
is part ::Array
and part Hash. It retains an order for the fields and allows duplicates just as an ::Array
would, but also allows you to access fields by name just as you could if they were in a Hash.
All rows returned by ::CSV
will be constructed from this class, if header row processing is activated.
Class Method Summary
- .new(headers, fields, header_row = false) ⇒ Row constructor
Instance Attribute Summary
-
#field_row? ⇒ Boolean
readonly
Returns
true
if this is a field row. -
#header_row? ⇒ Boolean
readonly
Returns
true
if this is a header row. -
#row
readonly
protected
Internal data format used to compare equality.
Instance Method Summary
-
#<<(field )
If a two-element
::Array
is provided, it is assumed to be a header and field and the pair is appended. -
#==(other)
Returns
true
if this row contains the same headers and fields in the same order asother
. -
#[](header_or_index, minimum_index = 0)
Alias for #field.
-
#[]=(header, value )
Looks up the field by the semantics described in
Row
.field() and assigns thevalue
. -
#delete(header)
Removes a pair from the row by
header
or #index. -
#delete_if(&block)
The provided
block
is passed a header and field for each pair in the row and expected to returntrue
orfalse
, depending on whether the pair should be deleted. -
#dig(index_or_header, *indexes)
Extracts the nested value specified by the sequence of #index or
header
objects by calling dig at each step, returning nil if any intermediate step is nil. -
#each(&block)
(also: #each_pair)
Yields each pair of the row as header and field tuples (much like iterating over a Hash).
-
#each_pair(&block)
Alias for #each.
-
#fetch(header)
This method will fetch the field value by
header
. -
#field(header)
(also: #[])
This method will return the field value by
header
or #index. -
#field?(data) ⇒ Boolean
Returns
true
ifdata
matches a field in this row, andfalse
otherwise. -
#fields(*headers_and_or_indices)
(also: #values_at)
This method accepts any number of arguments which can be headers, indices, Ranges of either, or two-element Arrays containing a header and offset.
-
#has_key?(header) ⇒ Boolean
(also: #include?, #key?, #member?, #header?)
Returns
true
if there is a field with the givenheader
. -
#header?(header)
Alias for #has_key?.
-
#headers
Returns the headers of this row.
-
#include?(header)
Alias for #has_key?.
-
#index(header)
This method will return the index of a field with the provided
header
. - #initialize_copy(other)
-
#inspect
A summary of fields, by header, in an ASCII compatible
::String
. -
#key?(header)
Alias for #has_key?.
-
#member?(header)
Alias for #has_key?.
-
#push(*args)
A shortcut for appending multiple fields.
- #to_ary
-
#to_csv(**options)
(also: #to_s)
Returns the row as a
::CSV
String. -
#to_h
(also: #to_hash)
Collapses the row into a simple Hash.
-
#to_hash
Alias for #to_h.
-
#to_s(**options)
Alias for #to_csv.
-
#values_at(*headers_and_or_indices)
Alias for #fields.
Constructor Details
.new(headers, fields, header_row = false) ⇒ Row
Constructs a new Row
from #headers and #fields, which are expected to be Arrays. If one ::Array
is shorter than the other, it will be padded with nil
objects.
The optional header_row
parameter can be set to true
to indicate, via Row
.header_row?() and Row
.field_row?(), that this is a header row. Otherwise, the row assumes to be a field row.
A Row
object supports the following ::Array
methods through delegation:
-
empty?()
-
length()
-
size()
Instance Attribute Details
#field_row? ⇒ Boolean
(readonly)
Returns true
if this is a field row.
# File 'lib/csv/row.rb', line 62
def field_row? not header_row? end
#header_row? ⇒ Boolean
(readonly)
Returns true
if this is a header row.
# File 'lib/csv/row.rb', line 57
def header_row? @header_row end
#row (readonly, protected)
Internal data format used to compare equality.
# File 'lib/csv/row.rb', line 43
attr_reader :row
Instance Method Details
#<<(field )
#<<(header_and_field_array )
#<<(header_and_field_hash )
If a two-element ::Array
is provided, it is assumed to be a header and field and the pair is appended. A Hash works the same way with the key being the header and the value being the field. Anything else is assumed to be a lone field which is appended with a nil
header.
This method returns the row for chaining.
#==(other)
Returns true
if this row contains the same headers and fields in the same order as other
.
#[](header_or_index, minimum_index = 0)
Alias for #field.
# File 'lib/csv/row.rb', line 96
alias_method :[], :field
#[]=(header, value )
#[]=(header, offset, value )
#[]=(index, value )
Looks up the field by the semantics described in Row
.field() and assigns the value
.
Assigning past the end of the row with an index will set all pairs between to [nil, nil]
. Assigning to an unused header appends the new pair.
# File 'lib/csv/row.rb', line 148
def []=(*args) value = args.pop if args.first.is_a? Integer if @row[args.first].nil? # extending past the end with index @row[args.first] = [nil, value] @row.map! { |pair| pair.nil? ? [nil, nil] : pair } else # normal index assignment @row[args.first][1] = value end else index = index(*args) if index.nil? # appending a field self << [args.first, value] else # normal header assignment @row[index][1] = value end end end
#delete(header)
#delete(header, offset)
#delete(index)
Removes a pair from the row by header
or #index. The pair is located as described in Row
.field(). The deleted pair is returned, or nil
if a pair could not be found.
# File 'lib/csv/row.rb', line 216
def delete(header_or_index, minimum_index = 0) if header_or_index.is_a? Integer # by index @row.delete_at(header_or_index) elsif i = index(header_or_index, minimum_index) # by header @row.delete_at(i) else [ ] end end
#delete_if(&block)
The provided block
is passed a header and field for each pair in the row and expected to return true
or false
, depending on whether the pair should be deleted.
This method returns the row for chaining.
If no block is given, an Enumerator is returned.
# File 'lib/csv/row.rb', line 235
def delete_if(&block) return enum_for(__method__) { size } unless block_given? @row.delete_if(&block) self # for chaining end
#dig(index_or_header, *indexes)
Extracts the nested value specified by the sequence of #index or header
objects by calling dig at each step, returning nil if any intermediate step is nil.
# File 'lib/csv/row.rb', line 356
def dig(index_or_header, *indexes) value = field(index_or_header) if value.nil? nil elsif indexes.empty? value else unless value.respond_to?(:dig) raise TypeError, "#{value.class} does not have \#dig method" end value.dig(*indexes) end end
#each(&block) Also known as: #each_pair
Yields each pair of the row as header and field tuples (much like iterating over a Hash). This method returns the row for chaining.
If no block is given, an Enumerator is returned.
Support for Enumerable.
# File 'lib/csv/row.rb', line 308
def each(&block) return enum_for(__method__) { size } unless block_given? @row.each(&block) self # for chaining end
#each_pair(&block)
Alias for #each.
# File 'lib/csv/row.rb', line 316
alias_method :each_pair, :each
#fetch(header)
#fetch(header) {|row| ... }
#fetch(header, default)
This method will fetch the field value by header
. It has the same behavior as Hash#fetch
: if there is a field with the given header
, its value is returned. Otherwise, if a block is given, it is yielded the header
and its result is returned; if a default
is given as the second argument, it is returned; otherwise a KeyError is raised.
# File 'lib/csv/row.rb', line 110
def fetch(header, *varargs) raise ArgumentError, "Too many arguments" if varargs.length > 1 pair = @row.assoc(header) if pair pair.last else if block_given? yield header elsif varargs.empty? raise KeyError, "key not found: #{header}" else varargs.first end end end
#field(header)
#field(header, offset)
#field(index)
Also known as: #[]
This method will return the field value by header
or #index. If a field is not found, nil
is returned.
When provided, offset
ensures that a header match occurs on or later than the offset
index. You can use this to find duplicate headers, without resorting to hard-coding exact indices.
# File 'lib/csv/row.rb', line 84
def field(header_or_index, minimum_index = 0) # locate the pair finder = (header_or_index.is_a?(Integer) || header_or_index.is_a?(Range)) ? :[] : :assoc pair = @row[minimum_index..-1].send(finder, header_or_index) # return the field if we have a pair if pair.nil? nil else header_or_index.is_a?(Range) ? pair.map(&:last) : pair.last end end
#field?(data) ⇒ Boolean
Returns true
if data
matches a field in this row, and false
otherwise.
#fields(*headers_and_or_indices) Also known as: #values_at
This method accepts any number of arguments which can be headers, indices, Ranges of either, or two-element Arrays containing a header and offset. Each argument will be replaced with a field lookup as described in Row
.field().
If called with no arguments, all fields are returned.
# File 'lib/csv/row.rb', line 251
def fields(*headers_and_or_indices) if headers_and_or_indices.empty? # return all fields--no arguments @row.map(&:last) else # or work like values_at() all = [] headers_and_or_indices.each do |h_or_i| if h_or_i.is_a? Range index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin : index(h_or_i.begin) index_end = h_or_i.end.is_a?(Integer) ? h_or_i.end : index(h_or_i.end) new_range = h_or_i.exclude_end? ? (index_begin...index_end) : (index_begin..index_end) all.concat(fields.values_at(new_range)) else all << field(*Array(h_or_i)) end end return all end end
#has_key?(header) ⇒ Boolean
Also known as: #include?, #key?, #member?, #header?
Returns true
if there is a field with the given header
.
# File 'lib/csv/row.rb', line 127
def has_key?(header) !!@row.assoc(header) end
#header?(header)
Alias for #has_key?.
# File 'lib/csv/row.rb', line 133
alias_method :header?, :has_key?
#headers
Returns the headers of this row.
# File 'lib/csv/row.rb', line 67
def headers @row.map(&:first) end
#include?(header)
Alias for #has_key?.
# File 'lib/csv/row.rb', line 130
alias_method :include?, :has_key?
#index(header)
#index(header, offset)
This method will return the index of a field with the provided header
. The offset
can be used to locate duplicate header names, as described in Row
.field().
# File 'lib/csv/row.rb', line 283
def index(header, minimum_index = 0) # find the pair index = headers[minimum_index..-1].index(header) # return the index at the right offset, if we found one index.nil? ? nil : index + minimum_index end
#initialize_copy(other)
[ GitHub ]# File 'lib/csv/row.rb', line 51
def initialize_copy(other) super @row = @row.dup end
#inspect
A summary of fields, by header, in an ASCII compatible ::String
.
# File 'lib/csv/row.rb', line 373
def inspect str = ["#<", self.class.to_s] each do |header, field| str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) << ":" << field.inspect end str << ">" begin str.join('') rescue # any encoding error str.map do |s| e = Encoding::Converter.asciicompat_encoding(s.encoding) e ? s.encode(e) : s.force_encoding("ASCII-8BIT") end.join('') end end
#key?(header)
Alias for #has_key?.
# File 'lib/csv/row.rb', line 131
alias_method :key?, :has_key?
#member?(header)
Alias for #has_key?.
# File 'lib/csv/row.rb', line 132
alias_method :member?, :has_key?
#push(*args)
A shortcut for appending multiple fields. Equivalent to:
args.each { |arg| csv_row << arg }
This method returns the row for chaining.
# File 'lib/csv/row.rb', line 200
def push(*args) args.each { |arg| self << arg } self # for chaining end
#to_ary
[ GitHub ]# File 'lib/csv/row.rb', line 340
alias_method :to_ary, :to_a
#to_csv(**options) Also known as: #to_s
[ GitHub ]# File 'lib/csv/row.rb', line 347
def to_csv(** ) fields.to_csv(** ) end
#to_h Also known as: #to_hash
Collapses the row into a simple Hash. Be warned that this discards field order and clobbers duplicate fields.
#to_hash
Alias for #to_h.
# File 'lib/csv/row.rb', line 338
alias_method :to_hash, :to_h
#to_s(**options)
Alias for #to_csv.
# File 'lib/csv/row.rb', line 350
alias_method :to_s, :to_csv
#values_at(*headers_and_or_indices)
Alias for #fields.
# File 'lib/csv/row.rb', line 272
alias_method :values_at, :fields