Class: CSV::Row (Ruby 2.2.3)
Description: Class : CSV::Row - Ruby 2.2.3

- Home
- Core 2.2.3
- Std-lib 2.2.3
- Downloads

Support for the Ruby 2.2 series has ended. See here for reference.

### Home Classes Methods

### In Files

- csv.rb

### Parent

Object

### Methods

- ::new
- #<<
- #==
- #[]
- #[]=
- #delete
- #delete_if
- #each
- #fetch
- #field
- #field?
- #field_row?
- #fields
- #has_key?
- #header?
- #header_row?
- #headers
- #include?
- #index
- #inspect
- #key?
- #member?
- #push
- #to_csv
- #to_hash
- #to_s
- #values_at

### Included Modules

- Enumerable

### Class/Module Index

Quicksearch

- CSV
- CSV::MalformedCSVError
- CSV::Row
- CSV::Table
- Object

No matching classes.

# CSV::Row

A CSV::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.

### Attributes

row[R]

Internal data format used to compare equality.

### Public Class Methods

new(headers, fields, header_row = false) click to toggle source

Construct a new CSV::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 #header_row? and #field_row?, that this is a header row. Otherwise, the row is assumes to be a field row.

A CSV::Row object supports the following Array methods through delegation:

- empty?()

- length()

- size()

                   # File csv.rb, line 235
    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

### Public Instance Methods

<<( field ) click to toggle source
<<( 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.

                   # File csv.rb, line 376
    def <<(arg)
      if arg.is_a?(Array) and arg.size == 2  # appending a header and name
        @row << arg
      elsif arg.is_a?(Hash)                  # append header and name pairs
        arg.each { |pair| @row << pair }
      else                                   # append field value
        @row << [nil, arg]
      end

      self  # for chaining
    end

==(other) click to toggle source

Returns `true` if this row contains the same headers and fields in the same order as `other`.

                   # File csv.rb, line 513
    def ==(other)
      return @row == other.row if other.is_a? CSV::Row
      @row == other
    end

[](header_or_index, minimum_index = 0) click to toggle source
Alias for: field
[]=( header, value ) click to toggle source
[]=( header, offset, value )
[]=( index, value )

Looks up the field by the semantics described in #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 csv.rb, line 343
    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 ) click to toggle source
delete( header, offset )
delete( index )

Used to remove a pair from the row by `header` or `index`. The pair is located as described in #field. The deleted pair is returned, or `nil` if a pair could not be found.

                   # File csv.rb, line 411
    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) click to toggle source

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.

                   # File csv.rb, line 428
    def delete_if(&block)
      @row.delete_if(&block)

      self  # for chaining
    end

each(&block) click to toggle source

Yields each pair of the row as header and field tuples (much like iterating over a Hash).

Support for Enumerable.

This method returns the row for chaining.

                   # File csv.rb, line 503
    def each(&block)
      @row.each(&block)

      self  # for chaining
    end

fetch( header ) click to toggle source
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 csv.rb, line 306
    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 ) click to toggle source
field( header, offset )
field( index )

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 csv.rb, line 284
    def field(header_or_index, minimum_index = 0)
      # locate the pair
      finder = header_or_index.is_a?(Integer) ? :[] : :assoc
      pair   = @row[minimum_index..-1].send(finder, header_or_index)

      # return the field if we have a pair
      pair.nil? ? nil : pair.last
    end

Also aliased as: []
field?(data) click to toggle source

Returns `true` if `data` matches a field in this row, and `false` otherwise.

                   # File csv.rb, line 489
    def field?(data)
      fields.include? data
    end

field_row?() click to toggle source

Returns `true` if this is a field row.

                   # File csv.rb, line 262
    def field_row?
      not header_row?
    end

fields(*headers_and_or_indices) click to toggle source

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 #field.

If called with no arguments, all fields are returned.

                   # File csv.rb, line 442
    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

Also aliased as: values_at
has_key?(header) click to toggle source

Returns `true` if there is a field with the given `header`.

                   # File csv.rb, line 323
    def has_key?(header)
      !!@row.assoc(header)
    end

Also aliased as: include?, key?, member?
header?(name) click to toggle source

Returns `true` if `name` is a header for this row, and `false` otherwise.

                   # File csv.rb, line 480
    def header?(name)
      headers.include? name
    end

Also aliased as: include?
header_row?() click to toggle source

Returns `true` if this is a header row.

                   # File csv.rb, line 257
    def header_row?
      @header_row
    end

headers() click to toggle source

Returns the headers of this row.

                   # File csv.rb, line 267
    def headers
      @row.map { |pair| pair.first }
    end

include?(header) click to toggle source
Alias for: has_key?
index( header ) click to toggle source
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 #field.

                   # File csv.rb, line 472
    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() click to toggle source

A summary of fields, by header, in an ASCII compatible String.

                   # File csv.rb, line 538
    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) click to toggle source
Alias for: has_key?
member?(header) click to toggle source
Alias for: has_key?
push(*args) click to toggle source

A shortcut for appending multiple fields. Equivalent to:

    args.each { |arg| csv_row << arg }

This method returns the row for chaining.

                   # File csv.rb, line 395
    def push(*args)
      args.each { |arg| self << arg }

      self  # for chaining
    end

to_csv(options = Hash.new) click to toggle source

Returns the row as a CSV String. Headers are not used. Equivalent to:

    csv_row.fields.to_csv( options )

                   # File csv.rb, line 532
    def to_csv(options = Hash.new)
      fields.to_csv(options)
    end

Also aliased as: to_s
to_hash() click to toggle source

Collapses the row into a simple Hash. Be warning that this discards field order and clobbers duplicate fields.

                   # File csv.rb, line 522
    def to_hash
      # flatten just one level of the internal Array
      Hash[*@row.inject(Array.new) { |ary, pair| ary.push(*pair) }]
    end

to_s(options = Hash.new) click to toggle source
Alias for: to_csv
values_at(*headers_and_or_indices) click to toggle source
Alias for: fields