類別 CSV::Table

CSV::Table

CSV::Table 實例表示 CSV 資料。(請參閱 類別 CSV).

實例可能有

實例方法

CSV::Table 有三組實例方法

建立 CSV::Table 實例

通常,透過使用標頭解析 CSV 來源來建立新的 CSV::Table 實例

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.class # => CSV::Table

您也可以直接建立實例。請參閱 ::new

標頭

如果表格有標頭,標頭會作為資料欄的標籤。每個標頭都是其欄的標籤。

CSV::Table 物件的標頭儲存在字串陣列中。

通常,標頭定義在 CSV 來源的第一列

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

如果沒有定義標頭,陣列會是空的

table = CSV::Table.new([])
table.headers # => []

存取模式

CSV::Table 提供三種模式來存取表格資料

CSV::Table 實例的存取模式會影響其部分實例方法的行為

列模式

Set 使用方法 by_row! 將表格設為列模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_row! # => #<CSV::Table mode:row row_count:4>

使用整數索引指定單一列

# Get a row.
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
# Set a row, then get it.
table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3])
table[1] # => #<CSV::Row "Name":"bam" "Value":3>

使用範圍指定一連串列

# Get rows.
table[1..2] # => [#<CSV::Row "Name":"bam" "Value":3>, #<CSV::Row "Name":"baz" "Value":"2">]
# Set rows, then get them.
table[1..2] = [
  CSV::Row.new(['Name', 'Value'], ['bat', 4]),
  CSV::Row.new(['Name', 'Value'], ['bad', 5]),
]
table[1..2] # => [["Name", #<CSV::Row "Name":"bat" "Value":4>], ["Value", #<CSV::Row "Name":"bad" "Value":5>]]

欄模式

Set 使用方法 by_col! 將表格設為欄模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_col! # => #<CSV::Table mode:col row_count:4>

使用整數索引指定欄

# Get a column.
table[0]
# Set a column, then get it.
table[0] = ['FOO', 'BAR', 'BAZ']
table[0] # => ["FOO", "BAR", "BAZ"]

使用字串標題指定欄

# Get a column.
table['Name'] # => ["FOO", "BAR", "BAZ"]
# Set a column, then get it.
table['Name'] = ['Foo', 'Bar', 'Baz']
table['Name'] # => ["Foo", "Bar", "Baz"]

混合模式

在混合模式中,您可以參考列或欄

Set 使用方法 by_col_or_row! 將表格設為混合模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>

使用整數索引指定單一列

# Get a row.
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
# Set a row, then get it.
table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3])
table[1] # => #<CSV::Row "Name":"bam" "Value":3>

使用範圍指定一連串列

# Get rows.
table[1..2] # => [#<CSV::Row "Name":"bam" "Value":3>, #<CSV::Row "Name":"baz" "Value":"2">]
# Set rows, then get them.
table[1] = CSV::Row.new(['Name', 'Value'], ['bat', 4])
table[2] = CSV::Row.new(['Name', 'Value'], ['bad', 5])
table[1..2] # => [["Name", #<CSV::Row "Name":"bat" "Value":4>], ["Value", #<CSV::Row "Name":"bad" "Value":5>]]

使用字串標題指定欄

# Get a column.
table['Name'] # => ["foo", "bat", "bad"]
# Set a column, then get it.
table['Name'] = ['Foo', 'Bar', 'Baz']
table['Name'] # => ["Foo", "Bar", "Baz"]

屬性

mode[R]

目前用於索引和反覆運算的存取模式。

table[R]

用於比較等號的內部資料格式。

公開類別方法

CSV::Table.new(array_of_rows, headers = nil) → csv_table 按一下以切換來源

傳回新的 CSV::Table 物件。

  • 引數 array_of_rows 必須是 CSV::Row 物件的陣列。

  • 如果提供引數 headers,它可以是字串陣列。


建立空的 CSV::Table 物件

table = CSV::Table.new([])
table # => #<CSV::Table mode:col_or_row row_count:1>

建立非空的 CSV::Table 物件

rows = [
  CSV::Row.new([], []),
  CSV::Row.new([], []),
  CSV::Row.new([], []),
]
table  = CSV::Table.new(rows)
table # => #<CSV::Table mode:col_or_row row_count:4>

如果引數 headers 是字串陣列,那些字串就會變成表格的標題

table = CSV::Table.new([], headers: ['Name', 'Age'])
table.headers # => ["Name", "Age"]

如果未提供引數 headers 且表格有列,標題會從第一列取得

rows = [
  CSV::Row.new(['Foo', 'Bar'], []),
  CSV::Row.new(['foo', 'bar'], []),
  CSV::Row.new(['FOO', 'BAR'], []),
]
table  = CSV::Table.new(rows)
table.headers # => ["Foo", "Bar"]

如果未提供引數 headers 且表格是空的(沒有列),標題也會是空的

table  = CSV::Table.new([])
table.headers # => []

如果引數 array_of_rows 不是陣列物件,就會引發例外狀況

# Raises NoMethodError (undefined method `first' for :foo:Symbol):
CSV::Table.new(:foo)

如果 array_of_rows 的元素不是 CSV::Table 物件,就會引發例外狀況

# Raises NoMethodError (undefined method `headers' for :foo:Symbol):
CSV::Table.new([:foo])
# File lib/csv/table.rb, line 199
def initialize(array_of_rows, headers: nil)
  @table = array_of_rows
  @headers = headers
  unless @headers
    if @table.empty?
      @headers = []
    else
      @headers = @table.first.headers
    end
  end

  @mode  = :col_or_row
end

公開實例方法

table << row_or_array → self 按一下以切換來源

如果 row_or_array 是 CSV::Row 物件,它會附加到表格

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

如果 row_or_array 是陣列,它會用來建立新的 CSV::Row 物件,然後將該物件附加到表格

table << ['bam', 4]
table[4] # => #<CSV::Row "Name":"bam" "Value":4>
# File lib/csv/table.rb, line 762
def <<(row_or_array)
  if row_or_array.is_a? Array  # append Array
    @table << Row.new(headers, row_or_array)
  else                         # append Row
    @table << row_or_array
  end

  self # for chaining
end
table == other_table → true 或 false 按一下以切換來源

如果 self 的每一列都 == other_table 的對應列,則傳回 true,否則傳回 false

存取模式不會影響結果。

相等的表格

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
other_table = CSV.parse(source, headers: true)
table == other_table # => true

列數不同

other_table.delete(2)
table == other_table # => false

最後一列不同

other_table << ['bat', 3]
table == other_table # => false
# File lib/csv/table.rb, line 965
def ==(other)
  return @table == other.table if other.is_a? CSV::Table
  @table == other
end
table[n] → 列或欄位資料 按一下以切換來源
table[range] → 列陣列或欄位資料陣列
table[header] → 欄位資料陣列

傳回表格中的資料;不會修改表格。


依整數索引擷取列
  • 格式:table[n],其中 n 為整數。

  • 存取模式::row:col_or_row

  • 傳回值:表格的第 n 列(如果該列存在);否則傳回 nil

如果該列存在,則傳回表格的第 n

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_row! # => #<CSV::Table mode:row row_count:4>
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">

如果 n 為負數,則從最後一列開始往回算

table[-1] # => #<CSV::Row "Name":"baz" "Value":"2">

如果 n 太大或太小,則傳回 nil

table[4] # => nil
table[-4] # => nil

如果存取模式為 :rown 不是整數,則擲回例外狀況

table.by_row! # => #<CSV::Table mode:row row_count:4>
# Raises TypeError (no implicit conversion of String into Integer):
table['Name']

依整數索引擷取欄
  • 格式:table[n],其中 n 為整數。

  • 存取模式::col

  • 傳回值:表格的第 n 欄(如果該欄存在);否則傳回長度為 self.sizenil 欄位陣列。

如果該欄存在,則傳回表格的第 n

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_col! # => #<CSV::Table mode:col row_count:4>
table[1] # => ["0", "1", "2"]

如果 n 為負數,則從最後一欄開始往回算

table[-2] # => ["foo", "bar", "baz"]

如果 n 太大或太小,則傳回 nil 欄位陣列

table[4] # => [nil, nil, nil]
table[-4] # => [nil, nil, nil]

依範圍擷取列
  • 格式:table[range],其中 range 為範圍物件。

  • 存取模式::row:col_or_row

  • 傳回值:表格中的列,從列 range.start 開始(如果這些列存在)。

傳回表格中的列,從列 range.first 開始(如果這些列存在)。

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_row! # => #<CSV::Table mode:row row_count:4>
rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]

如果列數太少,則傳回從 range.start 到最後的所有列

rows = table[1..50] # => #<CSV::Row "Name":"bar" "Value":"1">
rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]

特殊情況:如果 range.start == table.size,則傳回一個空陣列

table[table.size..50] # => []

如果 range.end 為負數,則從最後計算結束索引

rows = table[0..-1]
rows # => [#<CSV::Row "Name":"foo" "Value":"0">, #<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]

如果 range.start 為負數,則從最後計算開始索引

rows = table[-1..2]
rows # => [#<CSV::Row "Name":"baz" "Value":"2">]

如果 range.start 大於 table.size,則傳回 nil

table[4..4] # => nil

依範圍擷取欄
  • 格式:table[range],其中 range 為範圍物件。

  • 存取模式::col

  • 傳回值:表格中的欄位資料,從欄位 range.start 開始(如果這些欄位存在)。

如果欄位存在,傳回表格中的欄位值;這些值會按列排列

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

特殊情況:如果 range.start == headers.size,傳回一個由空陣列組成的陣列(大小:table.size

table[table.headers.size..50] # => [[], [], []]

如果 range.end 為負數,則從最後計算結束索引

table[0..-1] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]

如果 range.start 為負數,則從最後計算開始索引

table[-2..2] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]

如果 range.start 大於 table.size,傳回一個由 nil 值組成的陣列

table[4..4] # => [nil, nil, nil]

透過字串標題擷取欄位
  • 格式:table[header],其中 header 是字串標題。

  • 存取模式::col:col_or_row

  • 傳回值:如果該 header 存在,傳回表格中的欄位資料。

如果欄位存在,傳回表格中的欄位值

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_col! # => #<CSV::Table mode:col row_count:4>
table['Name'] # => ["foo", "bar", "baz"]
table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
col = table['Name']
col # => ["foo", "bar", "baz"]

修改傳回的欄位值不會修改表格

col[0] = 'bat'
col # => ["bat", "bar", "baz"]
table['Name'] # => ["foo", "bar", "baz"]

如果沒有該欄位,傳回一個由 nil 值組成的陣列

table['Nosuch'] # => [nil, nil, nil]
# File lib/csv/table.rb, line 514
def [](index_or_header)
  if @mode == :row or  # by index
     (@mode == :col_or_row and (index_or_header.is_a?(Integer) or index_or_header.is_a?(Range)))
    @table[index_or_header]
  else                 # by header
    @table.map { |row| row[index_or_header] }
  end
end
table[n] = row → row 按一下以切換來源
table[n] = field_or_array_of_fields → field_or_array_of_fields
table[header] = field_or_array_of_fields → field_or_array_of_fields

將資料放入表格中。


Set 透過整數索引設定列
  • 格式:table[n] = row,其中 n 是整數,row 是 CSV::Row 執行個體或欄位的陣列。

  • 存取模式::row:col_or_row

  • 傳回值:row

如果列存在,會將其取代

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
new_row = CSV::Row.new(['Name', 'Value'], ['bat', 3])
table.by_row! # => #<CSV::Table mode:row row_count:4>
return_value = table[0] = new_row
return_value.equal?(new_row) # => true # Returned the row
table[0].to_h # => {"Name"=>"bat", "Value"=>3}

使用存取模式 :col_or_row

table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
table[0] = CSV::Row.new(['Name', 'Value'], ['bam', 4])
table[0].to_h # => {"Name"=>"bam", "Value"=>4}

使用陣列而不是 CSV::Row,會繼承表格的標題

array = ['bad', 5]
return_value = table[0] = array
return_value.equal?(array) # => true # Returned the array
table[0].to_h # => {"Name"=>"bad", "Value"=>5}

如果列不存在,會透過新增列來延伸表格:視需要指派列為 nil

table.size # => 3
table[5] = ['bag', 6]
table.size # => 6
table[3] # => nil
table[4]# => nil
table[5].to_h # => {"Name"=>"bag", "Value"=>6}

請注意,nil 列實際上是 nil,而不是由 nil 欄位組成的列。


Set 透過整數索引設定欄位
  • 格式:table[n] = array_of_fields,其中 n 是整數,array_of_fields 是字串欄位的陣列。

  • 存取模式::col

  • 傳回值:array_of_fields

如果欄位存在,會將其取代

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
new_col = [3, 4, 5]
table.by_col! # => #<CSV::Table mode:col row_count:4>
return_value = table[1] = new_col
return_value.equal?(new_col) # => true # Returned the column
table[1] # => [3, 4, 5]
# The rows, as revised:
table.by_row! # => #<CSV::Table mode:row row_count:4>
table[0].to_h # => {"Name"=>"foo", "Value"=>3}
table[1].to_h # => {"Name"=>"bar", "Value"=>4}
table[2].to_h # => {"Name"=>"baz", "Value"=>5}
table.by_col! # => #<CSV::Table mode:col row_count:4>

如果值太少,會填入 nil

table[1] = [0]
table[1] # => [0, nil, nil]

如果值太多,會忽略額外的值

table[1] = [0, 1, 2, 3, 4]
table[1] # => [0, 1, 2]

如果只提供一個值,會將欄位中的所有欄位取代為該值

table[1] = 'bat'
table[1] # => ["bat", "bat", "bat"]

Set 透過字串標題設定欄位
  • 格式:table[header] = field_or_array_of_fields,其中 header 是字串標題,field_or_array_of_fields 是欄位值或字串欄位的陣列。

  • 存取模式::col:col_or_row

  • 傳回值:field_or_array_of_fields

如果欄位存在,會將其取代

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
new_col = [3, 4, 5]
table.by_col! # => #<CSV::Table mode:col row_count:4>
return_value = table['Value'] = new_col
return_value.equal?(new_col) # => true # Returned the column
table['Value'] # => [3, 4, 5]
# The rows, as revised:
table.by_row! # => #<CSV::Table mode:row row_count:4>
table[0].to_h # => {"Name"=>"foo", "Value"=>3}
table[1].to_h # => {"Name"=>"bar", "Value"=>4}
table[2].to_h # => {"Name"=>"baz", "Value"=>5}
table.by_col! # => #<CSV::Table mode:col row_count:4>

如果值太少,會填入 nil

table['Value'] = [0]
table['Value'] # => [0, nil, nil]

如果值太多,會忽略額外的值

table['Value'] = [0, 1, 2, 3, 4]
table['Value'] # => [0, 1, 2]

如果欄位不存在,則透過新增欄位來延伸表格

table['Note'] = ['x', 'y', 'z']
table['Note'] # => ["x", "y", "z"]
# The rows, as revised:
table.by_row!
table[0].to_h # => {"Name"=>"foo", "Value"=>0, "Note"=>"x"}
table[1].to_h # => {"Name"=>"bar", "Value"=>1, "Note"=>"y"}
table[2].to_h # => {"Name"=>"baz", "Value"=>2, "Note"=>"z"}
table.by_col!

如果只提供一個值,會將欄位中的所有欄位取代為該值

table['Value'] = 'bat'
table['Value'] # => ["bat", "bat", "bat"]
# File lib/csv/table.rb, line 649
def []=(index_or_header, value)
  if @mode == :row or  # by index
     (@mode == :col_or_row and index_or_header.is_a? Integer)
    if value.is_a? Array
      @table[index_or_header] = Row.new(headers, value)
    else
      @table[index_or_header] = value
    end
  else                 # set column
    unless index_or_header.is_a? Integer
      index = @headers.index(index_or_header) || @headers.size
      @headers[index] = index_or_header
    end
    if value.is_a? Array  # multiple values
      @table.each_with_index do |row, i|
        if row.header_row?
          row[index_or_header] = index_or_header
        else
          row[index_or_header] = value[i]
        end
      end
    else                  # repeated value
      @table.each do |row|
        if row.header_row?
          row[index_or_header] = index_or_header
        else
          row[index_or_header] = value
        end
      end
    end
  end
end
by_col → table_dup 按一下以切換來源

傳回 self 的重複資料,在欄位模式中(請參閱 欄位模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.mode # => :col_or_row
dup_table = table.by_col
dup_table.mode # => :col
dup_table.equal?(table) # => false # It's a dup

這可以用於串接方法呼叫,而不變更模式(但也會影響效能和記憶體使用)

dup_table.by_col['Name']

另請注意,對重複表格的變更不會影響原始表格。

# File lib/csv/table.rb, line 242
def by_col
  self.class.new(@table.dup).by_col!
end
by_col! → self 按一下以切換來源

self 的模式設定為欄位模式(請參閱 欄位模式);傳回 self

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.mode # => :col_or_row
table1 = table.by_col!
table.mode # => :col
table1.equal?(table) # => true # Returned self
# File lib/csv/table.rb, line 257
def by_col!
  @mode = :col

  self
end
by_col_or_row → table_dup 按一下以切換來源

傳回 self 的重複資料,在混合模式中(請參閱 混合模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true).by_col!
table.mode # => :col
dup_table = table.by_col_or_row
dup_table.mode # => :col_or_row
dup_table.equal?(table) # => false # It's a dup

這可以用於串接方法呼叫,而不變更模式(但也會影響效能和記憶體使用)

dup_table.by_col_or_row['Name']

另請注意,對重複表格的變更不會影響原始表格。

# File lib/csv/table.rb, line 280
def by_col_or_row
  self.class.new(@table.dup).by_col_or_row!
end
by_col_or_row! → self 按一下以切換來源

self 的模式設定為混合模式(請參閱 混合模式);傳回 self

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true).by_col!
table.mode # => :col
table1 = table.by_col_or_row!
table.mode # => :col_or_row
table1.equal?(table) # => true # Returned self
# File lib/csv/table.rb, line 295
def by_col_or_row!
  @mode = :col_or_row

  self
end
by_row → table_dup 按一下以切換來源

傳回 self 的重複資料,在列模式中(請參閱 列模式

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.mode # => :col_or_row
dup_table = table.by_row
dup_table.mode # => :row
dup_table.equal?(table) # => false # It's a dup

這可以用於串接方法呼叫,而不變更模式(但也會影響效能和記憶體使用)

dup_table.by_row[1]

另請注意,對重複表格的變更不會影響原始表格。

# File lib/csv/table.rb, line 318
def by_row
  self.class.new(@table.dup).by_row!
end
by_row! → self 按一下以切換來源

self 的模式設定為列模式(請參閱 列模式);傳回 self

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.mode # => :col_or_row
table1 = table.by_row!
table.mode # => :row
table1.equal?(table) # => true # Returned self
# File lib/csv/table.rb, line 333
def by_row!
  @mode = :row

  self
end
delete(*indexes) → deleted_values 按一下以切換來源
delete(*headers) → deleted_values

如果存取模式為 :row:col_or_row,且每個引數都是整數或範圍,則傳回已刪除的列。否則,傳回已刪除的欄位資料。

在任一種情況下,傳回的值都按照引數指定的順序排列。引數可以重複。


傳回列,作為 CSV::Row 物件陣列。

一個索引

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

兩個索引

table = CSV.parse(source, headers: true)
deleted_values = table.delete(2, 0)
deleted_values # => [#<CSV::Row "Name":"baz" "Value":"2">, #<CSV::Row "Name":"foo" "Value":"0">]

傳回欄位資料,作為欄位陣列。

一個標頭

table = CSV.parse(source, headers: true)
deleted_values = table.delete('Name')
deleted_values # => ["foo", "bar", "baz"]

兩個標頭

table = CSV.parse(source, headers: true)
deleted_values = table.delete('Value', 'Name')
deleted_values # => [["0", "1", "2"], ["foo", "bar", "baz"]]
# File lib/csv/table.rb, line 834
def delete(*indexes_or_headers)
  if indexes_or_headers.empty?
    raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
  end
  deleted_values = indexes_or_headers.map do |index_or_header|
    if @mode == :row or  # by index
        (@mode == :col_or_row and index_or_header.is_a? Integer)
      @table.delete_at(index_or_header)
    else                 # by header
      if index_or_header.is_a? Integer
        @headers.delete_at(index_or_header)
      else
        @headers.delete(index_or_header)
      end
      @table.map { |row| row.delete(index_or_header).last }
    end
  end
  if indexes_or_headers.size == 1
    deleted_values[0]
  else
    deleted_values
  end
end
delete_if {|row_or_column| ... } → self 按一下以切換來源

移除區塊傳回真值的行或欄;傳回 self

當存取模式為 :row:col_or_row 時移除列;使用每個 CSV::Row 物件呼叫區塊

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_row! # => #<CSV::Table mode:row row_count:4>
table.size # => 3
table.delete_if {|row| row['Name'].start_with?('b') }
table.size # => 1

當存取模式為 :col 時移除欄;使用每個欄作為包含標頭和欄位陣列的 2 元素陣列呼叫區塊

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_col! # => #<CSV::Table mode:col row_count:4>
table.headers.size # => 2
table.delete_if {|column_data| column_data[1].include?('2') }
table.headers.size # => 1

如果未提供區塊,則傳回新的 Enumerator

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.delete_if # => #<Enumerator: #<CSV::Table mode:col_or_row row_count:4>:delete_if>
# File lib/csv/table.rb, line 887
def delete_if(&block)
  return enum_for(__method__) { @mode == :row or @mode == :col_or_row ? size : headers.size } unless block_given?

  if @mode == :row or @mode == :col_or_row  # by index
    @table.delete_if(&block)
  else                                      # by header
    headers.each do |header|
      delete(header) if yield([header, self[header]])
    end
  end

  self # for chaining
end
dig(index_or_header, *index_or_headers) 按一下以切換來源

透過在每個步驟呼叫 dig,擷取由 indexheader 物件序列指定的巢狀值,如果任何中間步驟為 nil,則傳回 nil。

# File lib/csv/table.rb, line 1021
def dig(index_or_header, *index_or_headers)
  value = self[index_or_header]
  if value.nil?
    nil
  elsif index_or_headers.empty?
    value
  else
    unless value.respond_to?(:dig)
      raise TypeError, "#{value.class} does not have \#dig method"
    end
    value.dig(*index_or_headers)
  end
end
each {|row_or_column| ... ) → self 按一下以切換來源

使用每個列或欄呼叫區塊;傳回 self

當存取模式為 :row:col_or_row 時,使用每個 CSV::Row 物件呼叫區塊

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.by_row! # => #<CSV::Table mode:row row_count:4>
table.each {|row| p row }

輸出

#<CSV::Row "Name":"foo" "Value":"0">
#<CSV::Row "Name":"bar" "Value":"1">
#<CSV::Row "Name":"baz" "Value":"2">

當存取模式為 :col 時,使用每個欄作為包含標頭和欄位陣列的 2 元素陣列呼叫區塊

table.by_col! # => #<CSV::Table mode:col row_count:4>
table.each {|column_data| p column_data }

輸出

["Name", ["foo", "bar", "baz"]]
["Value", ["0", "1", "2"]]

如果未提供區塊,則傳回新的 Enumerator

table.each # => #<Enumerator: #<CSV::Table mode:col row_count:4>:each>
# File lib/csv/table.rb, line 930
def each(&block)
  return enum_for(__method__) { @mode == :col ? headers.size : size } unless block_given?

  if @mode == :col
    headers.each.with_index do |header, i|
      yield([header, @table.map {|row| row[header, i]}])
    end
  else
    @table.each(&block)
  end

  self # for chaining
end
headers → array_of_headers 按一下以切換來源

傳回包含表格字串標頭的新陣列。

如果表格不為空,則傳回第一列的標頭

rows = [
  CSV::Row.new(['Foo', 'Bar'], []),
  CSV::Row.new(['FOO', 'BAR'], []),
  CSV::Row.new(['foo', 'bar'], []),
]
table  = CSV::Table.new(rows)
table.headers # => ["Foo", "Bar"]
table.delete(0)
table.headers # => ["FOO", "BAR"]
table.delete(0)
table.headers # => ["foo", "bar"]

如果表格為空,則傳回表格中標頭的副本

table.delete(0)
table.headers # => ["Foo", "Bar"]
# File lib/csv/table.rb, line 360
def headers
  if @table.empty?
    @headers.dup
  else
    @table.first.headers
  end
end
inspect → string 按一下以切換來源

傳回顯示表格的 US-ASCII 編碼字串

  • 類別:CSV::Table

  • 存取模式::row:col:col_or_row

  • 大小:Row 計數,包括標題列。

範例

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.inspect # => "#<CSV::Table mode:col_or_row row_count:4>\nName,Value\nfoo,0\nbar,1\nbaz,2\n"
# File lib/csv/table.rb, line 1048
def inspect
  inspected = +"#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>"
  summary = to_csv(limit: 5)
  inspected << "\n" << summary if summary.encoding.ascii_compatible?
  inspected
end
push(*rows_or_arrays) → self 按一下以切換來源

附加多列的捷徑。等於

rows.each {|row| self << row }

每個參數可以是 CSV::Row 物件或陣列

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
rows = [
  CSV::Row.new(table.headers, ['bat', 3]),
  ['bam', 4]
]
table.push(*rows)
table[3..4] # => [#<CSV::Row "Name":"bat" "Value":3>, #<CSV::Row "Name":"bam" "Value":4>]
# File lib/csv/table.rb, line 788
def push(*rows)
  rows.each { |row| self << row }

  self # for chaining
end
to_a → array_of_arrays 按一下以切換來源

將表格作為陣列的陣列傳回;標頭在第一列

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.to_a # => [["Name", "Value"], ["foo", "0"], ["bar", "1"], ["baz", "2"]]
# File lib/csv/table.rb, line 978
def to_a
  array = [headers]
  @table.each do |row|
    array.push(row.fields) unless row.header_row?
  end

  array
end
to_csv(**options) → csv_string 按一下以切換來源

將表格作為 CSV 字串傳回。請參閱 產生選項

將選項 write_headers 預設為 true

source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
table.to_csv # => "Name,Value\nfoo,0\nbar,1\nbaz,2\n"

如果選項 write_headers 指定為 false,則省略標頭(請參閱 {選項 write_headers}

table.to_csv(write_headers: false) # => "foo,0\nbar,1\nbaz,2\n"

如果選項 limit 指定為 2 之類的值,則限制列數

table.to_csv(limit: 2) # => "Name,Value\nfoo,0\nbar,1\n"
# File lib/csv/table.rb, line 1004
def to_csv(write_headers: true, limit: nil, **options)
  array = write_headers ? [headers.to_csv(**options)] : []
  limit ||= @table.size
  limit = @table.size + 1 + limit if limit < 0
  limit = 0 if limit < 0
  @table.first(limit).each do |row|
    array.push(row.fields.to_csv(**options)) unless row.header_row?
  end

  array.join("")
end
別名為:to_s
to_s
別名為:to_csv
values_at(*indexes) → array_of_rows 按一下以切換來源
values_at(*headers) → array_of_columns_data

如果存取模式為 :row:col_or_row,且每個參數都是整數或範圍,則傳回列。否則,傳回欄資料。

在任一種情況下,傳回的值都按照引數指定的順序排列。引數可以重複。


傳回列,作為 CSV::Row 物件陣列。

無參數

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

一個索引

values = table.values_at(0)
values # => [#<CSV::Row "Name":"foo" "Value":"0">]

兩個索引

values = table.values_at(2, 0)
values # => [#<CSV::Row "Name":"baz" "Value":"2">, #<CSV::Row "Name":"foo" "Value":"0">]

一個範圍

values = table.values_at(1..2)
values # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]

範圍和索引

values = table.values_at(0..1, 1..2, 0, 2)
pp values

輸出

[#<CSV::Row "Name":"foo" "Value":"0">,
 #<CSV::Row "Name":"bar" "Value":"1">,
 #<CSV::Row "Name":"bar" "Value":"1">,
 #<CSV::Row "Name":"baz" "Value":"2">,
 #<CSV::Row "Name":"foo" "Value":"0">,
 #<CSV::Row "Name":"baz" "Value":"2">]

傳回欄資料作為列陣列,每個陣列包含該列指定的欄資料

values = table.values_at('Name')
values # => [["foo"], ["bar"], ["baz"]]
values = table.values_at('Value', 'Name')
values # => [["0", "foo"], ["1", "bar"], ["2", "baz"]]
# File lib/csv/table.rb, line 734
def values_at(*indices_or_headers)
  if @mode == :row or  # by indices
     ( @mode == :col_or_row and indices_or_headers.all? do |index|
                                  index.is_a?(Integer)         or
                                  ( index.is_a?(Range)         and
                                    index.first.is_a?(Integer) and
                                    index.last.is_a?(Integer) )
                                end )
    @table.values_at(*indices_or_headers)
  else                 # by headers
    @table.map { |row| row.values_at(*indices_or_headers) }
  end
end