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.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)
Used to remove 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. -
#each(&block)
Yields each pair of the row as header and field tuples (much like iterating over a Hash).
-
#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?)
Returns
true
if there is a field with the givenheader
. -
#header?(name) ⇒ Boolean
(also: #include?)
Returns
true
ifname
is a header for this row, andfalse
otherwise. -
#headers
Returns the headers of this row.
-
#include?(name)
Alias for #header?.
-
#index(header)
This method will return the index of a field with the provided
header
. -
#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_csv(options = Hash.new)
(also: #to_s)
Returns the row as a ::CSV String.
-
#to_hash
Collapses the row into a simple Hash.
-
#to_s(options = Hash.new)
Alias for #to_csv.
-
#values_at(*headers_and_or_indices)
Alias for #fields.
Constructor Details
.new(headers, fields, header_row = false) ⇒ Row
Construct 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 is assumes to be a field row.
A Row
object supports the following ::Array methods through delegation:
-
empty?()
-
length()
-
size()
# File 'lib/csv.rb', line 237
def initialize(headers, fields, header_row = false) @header_row = header_row headers.each { |h| h.freeze if h.is_a? String } # handle extra headers or fields @row = if headers.size >= fields.size headers.zip(fields) else fields.zip(headers).map { |pair| pair.reverse! } end end
Instance Attribute Details
#field_row? ⇒ Boolean
(readonly)
Returns true
if this is a field row.
# File 'lib/csv.rb', line 264
def field_row? not header_row? end
#header_row? ⇒ Boolean
(readonly)
Returns true
if this is a header row.
# File 'lib/csv.rb', line 259
def header_row? @header_row end
#row (readonly, protected)
Internal data format used to compare equality.
# File 'lib/csv.rb', line 250
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.rb', line 298
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.rb', line 349
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)
Used to remove 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.rb', line 417
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.rb', line 436
def delete_if(&block) block or return enum_for(__method__) { size } @row.delete_if(&block) self # for chaining end
#each(&block)
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.rb', line 513
def each(&block) block or return enum_for(__method__) { size } @row.each(&block) self # for chaining end
#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.rb', line 312
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.rb', line 286
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.rb', line 452
def fields(*headers_and_or_indices) if headers_and_or_indices.empty? # return all fields--no arguments @row.map { |pair| pair.last } else # or work like values_at() headers_and_or_indices.inject(Array.new) do |all, h_or_i| all + 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) fields.values_at(new_range) else [field(*Array(h_or_i))] end end end end
#has_key?(header) ⇒ Boolean
Also known as: #include?, #key?, #member?
Returns true
if there is a field with the given header
.
# File 'lib/csv.rb', line 329
def has_key?(header) !!@row.assoc(header) end
#header?(name) ⇒ Boolean
Also known as: #include?
Returns true
if name
is a header for this row, and false
otherwise.
#headers
Returns the headers of this row.
# File 'lib/csv.rb', line 269
def headers @row.map { |pair| pair.first } end
#include?(name)
Alias for #header?.
# File 'lib/csv.rb', line 332
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.rb', line 482
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
#inspect
A summary of fields, by header, in an ASCII compatible ::String.
# File 'lib/csv.rb', line 550
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.rb', line 333
alias_method :key?, :has_key?
#member?(header)
Alias for #has_key?.
# File 'lib/csv.rb', line 334
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.rb', line 401
def push(*args) args.each { |arg| self << arg } self # for chaining end
#to_csv(options = Hash.new) Also known as: #to_s
[ GitHub ]#to_hash
Collapses the row into a simple Hash. Be warned that this discards field order and clobbers duplicate fields.
#to_s(options = Hash.new)
Alias for #to_csv.
# File 'lib/csv.rb', line 547
alias_method :to_s, :to_csv
#values_at(*headers_and_or_indices)
Alias for #fields.
# File 'lib/csv.rb', line 471
alias_method :values_at, :fields