Spec-Zone.ru › Ruby 3.1

class CSV::Row

Родительский класс:
Object
Включенные модули:
Enumerable

Объект CSV::Row является частью Array и частью Hash. Он сохраняет порядок полей и допускает дубликаты, как и Array, но также позволяет получать доступ к полям по имени, как если бы они находились в Hash.

Все строки, возвращаемые CSV, будут созданы из этого класса, если активирована обработка строки заголовков.

Атрибуты

row[R]

Внутренний формат данных, используемый для сравнения равенства.

Публичные методы класса

new(headers, fields, header_row = false) Show source
# File lib/csv/row.rb, line 30
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).each(&:reverse!)
  end
end

Создает новый объект CSV::Row из headers и fields, которые должны быть массивами. Если один Array короче другого, он будет дополнен объектами nil.

Необязательный параметр header_row может быть установлен в true для указания, через CSV::Row.header_row?() и CSV::Row.field_row?(), что это строка заголовка. В противном случае строка считается строкой данных.

Объект CSV::Row поддерживает следующие методы Array через делегирование:

  • empty?()

  • length()

  • size()

Публичные методы экземпляра

row << [header, value] → self Показать исходный код
row << hash → self
row << value → self
# File lib/csv/row.rb, line 310
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

Добавляет поле в self; возвращает self:

Если аргумент является 2-элементным массивом [header, value], добавляется поле с заданным header и value:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row << ['NAME', 'Bat']
row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" "NAME":"Bat">

Если аргумент является хешем, каждая пара key-value добавляется как поле с заголовком key и значением value.

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row << {NAME: 'Bat', name: 'Bam'}
row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" NAME:"Bat" name:"Bam">

В противном случае, заданное value добавляется как поле без заголовка.

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row << 'Bag'
row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bag">
==(other) Показать исходный код
# File lib/csv/row.rb, line 522
def ==(other)
  return @row == other.row if other.is_a? CSV::Row
  @row == other
end

Возвращает true, если эта строка содержит те же заголовки и поля в том же порядке, что и other.

[](header_or_index, minimum_index = 0)
Псевдоним для: field
row[index] = value → value Показать исходный код
row[header, offset] = value → value
row[header] = value → value
# File lib/csv/row.rb, line 260
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

Присваивает значение поля для заданного index или header; возвращает value.

Присваивание значения поля по целочисленному индексу:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row[0] = 'Bat'
row[1] = 3
row # => #<CSV::Row "Name":"Bat" "Value":3>

Считает в обратном порядке от последнего столбца, если index отрицателен:

row[-1] = 4
row[-2] = 'Bam'
row # => #<CSV::Row "Name":"Bam" "Value":4>

Расширяет строку с nil:nil, если положительное index отсутствует в строке:

row[4] = 5
row # => #<CSV::Row "Name":"bad" "Value":4 nil:nil nil:nil nil:5>

Вызывает IndexError, если отрицательное index слишком мало (слишком далеко от нуля).

Присваивание значения поля по заголовку (первое найденное):

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row['Name'] = 'Bat'
row # => #<CSV::Row "Name":"Bat" "Name":"Bar" "Name":"Baz">

Присваивание значения поля по заголовку, игнорируя offset ведущих полей:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row['Name', 2] = 4
row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":4>

Добавление нового поля по (новому) заголовку:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row['New'] = 6
row# => #<CSV::Row "Name":"foo" "Value":"0" "New":6>
delete(index) → [header, value] or nil Показать исходный код
delete(header) → [header, value] or empty_array
delete(header, offset) → [header, value] or empty_array
# File lib/csv/row.rb, line 372
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

Удаляет указанное поле из self; возвращает 2-элементный массив [header, value], если поле существует.

Если задан целочисленный аргумент index, удаляет и возвращает поле с смещением index, или возвращает nil, если поле не существует:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.delete(1) # => ["Name", "Bar"]
row.delete(50) # => nil

В противном случае, если задан единственный аргумент header, удаляет и возвращает первое найденное поле с заданным заголовком, или возвращает новый пустой массив, если поле не существует:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.delete('Name') # => ["Name", "Foo"]
row.delete('NAME') # => []

Если заданы аргументы header и целочисленный аргумент offset, удаляет и возвращает первое найденное поле с заданным заголовком, чей index не меньше, чем offset:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.delete('Name', 1) # => ["Name", "Bar"]
row.delete('NAME', 1) # => []
delete_if {|header, value| ... } → self Показать исходный код
# File lib/csv/row.rb, line 397
def delete_if(&block)
  return enum_for(__method__) { size } unless block_given?

  @row.delete_if(&block)

  self  # for chaining
end

Удаляет поля из self по выбору блока; возвращает self.

Удаляет каждое поле, для которого блок возвращает истинное значение:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.delete_if {|header, value| value.start_with?('B') } # => true
row # => #<CSV::Row "Name":"Foo">
row.delete_if {|header, value| header.start_with?('B') } # => false

Если блок не задан, возвращает новый перечислитель:

row.delete_if # => #<Enumerator: #<CSV::Row "Name":"Foo">:delete_if>
dig(index_or_header, *identifiers) → object Показать исходный код
# File lib/csv/row.rb, line 582
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

Находит и возвращает объект во вложенном объекте, указанный index_or_header и specifiers.

Вложенные объекты могут быть экземплярами различных классов. См. Dig Methods.

Примеры:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.dig(1) # => "0"
row.dig('Value') # => "0"
row.dig(5) # => nil
each(&block) Показать исходный код
# File lib/csv/row.rb, line 508
def each(&block)
  return enum_for(__method__) { size } unless block_given?

  @row.each(&block)

  self  # for chaining
end

Возвращает каждую пару строки в виде кортежей заголовок-поле (подобно итерации по Hash). Этот метод возвращает строку для цепочки вызовов.

Если блок не задан, возвращается Enumerator.

Поддержка для Enumerable.

Также известен как: each_pair
each_pair(&block)
Псевдоним для: each
fetch(header) Показать исходный код
fetch(header, default)
fetch(header) {|row| ... }
# File lib/csv/row.rb, line 179
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

Возвращает значение поля, указанное header.

С одним аргументом header, возвращает значение поля для этого заголовка (первое найденное):

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.fetch('Name') # => "Foo"

Вызывает исключение KeyError, если заголовок не существует.

С аргументами header и default, возвращает значение поля для заголовка (первое найденное), если заголовок существует, в противном случае возвращает default:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.fetch('Name', '') # => "Foo"
row.fetch(:nosuch, '') # => ""

С аргументом header и заданным блоком, возвращает значение поля для заголовка (первое найденное), если заголовок существует; в противном случае вызывает блок и возвращает его возвращаемое значение:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.fetch('Name') {|header| fail 'Cannot happen' } # => "Foo"
row.fetch(:nosuch) {|header| "Header '#{header} not found'" } # => "Header 'nosuch not found'"
field(index) Показать исходный код
field(header)
field(header, offset)
# File lib/csv/row.rb, line 124
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].public_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

Возвращает значение поля для заданного index или header.

Получение значения поля по целочисленному индексу:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.field(0) # => "foo"
row.field(1) # => "bar"

Считает в обратном порядке от последнего столбца, если index отрицателен:

row.field(-1) # => "0"
row.field(-2) # => "foo"

Возвращает nil, если index вне диапазона:

row.field(2) # => nil
row.field(-3) # => nil

Получение значения поля по заголовку (первое найденное):

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.field('Name') # => "Foo"

Получение значения поля по заголовку, игнорируя offset ведущих полей:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.field('Name', 2) # => "Baz"

Возвращает nil, если заголовок не существует.

Также известен как: []
field?(data) Показать исходный код
# File lib/csv/row.rb, line 494
def field?(data)
  fields.include? data
end

Возвращает true, если data соответствует полю в этой строке, и false в противном случае.

field_row? → true or false Показать исходный код
# File lib/csv/row.rb, line 69
def field_row?
  not header_row?
end

Возвращает true, если это строка поля, false в противном случае.

fields(*specifiers) Show source
# File lib/csv/row.rb, line 451
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

Возвращает значения полей в соответствии с заданными specifiers, которые могут быть любой комбинацией:

  • Целочисленный индекс.

  • Диапазон целочисленных индексов.

  • 2-элементный массив, содержащий заголовок и смещение.

  • Заголовок.

  • Диапазон заголовков.

Для specifier в одном из первых четырех случаев выше возвращает результат self.field(specifier); см. field.

Хотя может быть любое количество specifiers, примеры здесь будут иллюстрировать по одному за раз.

Когда спецификатор является целочисленным index, возвращает self.field(index)L

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.fields(1) # => ["Bar"]

Когда спецификатор является диапазоном целых чисел range, возвращает self.field(range):

row.fields(1..2) # => ["Bar", "Baz"]

Когда спецификатор является 2-элементным массивом array, возвращает self.field(array)L

row.fields('Name', 1) # => ["Foo", "Bar"]

Когда спецификатор является заголовком header, возвращает self.field(header)L

row.fields('Name') # => ["Foo"]

Когда спецификатор является диапазоном заголовков range, формирует новый диапазон new_range из индексов range.start и range.end, и возвращает self.field(new_range):

source = "Name,NAME,name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.fields('Name'..'NAME') # => ["Foo", "Bar"]

Возвращает все поля, если аргумент не задан:

row.fields # => ["Foo", "Bar", "Baz"]
Также имеет псевдоним: values_at
has_key?(header) Show source
# File lib/csv/row.rb, line 200
def has_key?(header)
  !!@row.assoc(header)
end

Возвращает true, если существует поле с заданным header, false в противном случае.

Также имеет псевдоним: include?, key?, member?, header?
header?(header)
Псевдоним для: has_key?
header_row? → true or false Show source
# File lib/csv/row.rb, line 61
def header_row?
  @header_row
end

Возвращает true, если это строка заголовка, false в противном случае.

headers Show source
# File lib/csv/row.rb, line 81
def headers
  @row.map(&:first)
end

Возвращает заголовки для этой строки:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table.first
row.headers # => ["Name", "Value"]
include?(header)
Псевдоним для: has_key?
index( header ) Show source
index( header, offset )
# File lib/csv/row.rb, line 483
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

Этот метод вернет индекс поля с предоставленным header. offset может использоваться для поиска дубликатов имен заголовков, как описано в CSV::Row.field().

initialize_copy(other) Show source
# File lib/csv/row.rb, line 51
def initialize_copy(other)
  super_return_value = super
  @row = @row.collect(&:dup)
  super_return_value
end
Вызывает метод суперкласса
inspect → string Show source
# File lib/csv/row.rb, line 607
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

Возвращает совместимую с ASCII строку, показывающую:

  • Class CSV::Row.

  • Пары заголовок-значение.

Пример:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.inspect # => "#<CSV::Row \"Name\":\"foo\" \"Value\":\"0\">"
key?(header)
Псевдоним для: has_key?
member?(header)
Псевдоним для: has_key?
push(*values) →self Show source
# File lib/csv/row.rb, line 331
def push(*args)
  args.each { |arg| self << arg }

  self  # for chaining
end

Добавляет каждое из заданных values к self в качестве поля; возвращает self:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.push('Bat', 'Bam')
row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bat" nil:"Bam">
to_csv → csv_string Show source
# File lib/csv/row.rb, line 561
def to_csv(**options)
  fields.to_csv(**options)
end

Возвращает строку как CSV String. Заголовки не включены:

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.to_csv # => "foo,0\n"
Также имеет псевдоним: to_s
to_h → hash Show source
# File lib/csv/row.rb, line 542
def to_h
  hash = {}
  each do |key, _value|
    hash[key] = self[key] unless hash.key?(key)
  end
  hash
end

Возвращает новый Hash, образованный путем добавления каждой пары заголовок-значение в self в качестве пары ключ-значение в Hash.

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.to_h # => {"Name"=>"foo", "Value"=>"0"}

Порядок заголовков сохраняется, но повторяющиеся заголовки игнорируются:

source = "Name,Name,Name\nFoo,Bar,Baz\n"
table = CSV.parse(source, headers: true)
row = table[0]
row.to_h # => {"Name"=>"Foo"}
Также имеет псевдоним: to_hash
to_hash()
Псевдоним для: to_h
to_s(**options)
Псевдоним для: to_csv
values_at(*headers_and_or_indices)
Псевдоним для: fields

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API