類別 CSV::Table
CSV::Table¶ ↑
CSV::Table 實例表示 CSV 資料。(請參閱 類別 CSV).
實例可能有
-
列:每個都是 Table::Row 物件。
-
標頭:欄的標籤。
實例方法¶ ↑
CSV::Table 有三組實例方法
-
它自己內部定義的實例方法。
-
模組
Enumerable
包含的方法。 -
委派給類別
Array
的方法。
建立 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 實例的存取模式會影響其部分實例方法的行為
列模式¶ ↑
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>]]
欄模式¶ ↑
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"]
屬性
目前用於索引和反覆運算的存取模式。
用於比較等號的內部資料格式。
公開類別方法
傳回新的 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
公開實例方法
如果 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
如果 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]
,其中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
如果存取模式為 :row
而 n
不是整數,則擲回例外狀況
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.size
的nil
欄位陣列。
如果該欄存在,則傳回表格的第 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
將資料放入表格中。
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
傳回 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
將 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
傳回 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
將 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
傳回 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
將 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
如果存取模式為 :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
移除區塊傳回真值的行或欄;傳回 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
或 header
物件序列指定的巢狀值,如果任何中間步驟為 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
使用每個列或欄呼叫區塊;傳回 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
傳回包含表格字串標頭的新陣列。
如果表格不為空,則傳回第一列的標頭
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
傳回顯示表格的 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
附加多列的捷徑。等於
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
將表格作為陣列的陣列傳回;標頭在第一列
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
將表格作為 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
如果存取模式為 :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