class CSV::Table

[edit]

extend: Forwardable

要約

CSV::Table は CSV ドキュメントを表す二次元のデータ構造です。行単位や列単位の操作を行うことが出来ます。また必要であれば CSV に戻すこともできます。

ヘッダ行の処理が有効である場合、CSV から返されるテーブルは全てこのクラスから構築されます。

以下のメソッドを Array に委譲します。

アクセスモード

以下の三種類のモードがあります。

:col_or_row

デフォルトはこのモードです。このマニュアル内ではミックスモードと呼んでいます。行単位でアクセスするか列単位でアクセスするか自動的に判断します。

:row

ロウモード。テーブルに行単位でアクセスします。

:column

カラムモード。テーブルに列単位でアクセスします。

目次

特異メソッド
インスタンスメソッド
protectedメソッド

継承しているメソッド

Enumerableから継承しているメソッド

特異メソッド

new(array_of_rows) -> CSV::Table[permalink][rdoc][edit]

自身を初期化します。

全ての行が同じヘッダを持つことを仮定しています。

[PARAM] array_of_rows:
CSV::Row のインスタンスの配列を指定します。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.to_a # => [["header1", "header2"], ["row1_1", "row1_2"], ["row2_1", "row2_2"]]

インスタンスメソッド

self << row_or_array -> self[permalink][rdoc][edit]

自身の最後に新しい行を追加します。

[PARAM] row_or_array:
CSV::Row のインスタンスか配列を指定します。配列を指定した場合は CSV::Row に変換されます。
[RETURN]
メソッドチェーンのために自身を返します。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1])
table << row2
table.to_a # => [["header1", "header2"], ["row1_1", "row1_2"], ["row2_1", "row2_2"]]
self == other -> bool[permalink][rdoc][edit]

自身の全ての行が比較対象と同じである場合は真を返します。そうでない場合は偽を返します。

[PARAM] other:
CSV::Table を指定します。


require "csv"

row1_1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row1_2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
row2_1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2_2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table1 = CSV::Table.new([row1_1, row1_2])
table2 = CSV::Table.new([row2_1, row2_2])
table1 == table2 # => true
table2 << CSV::Row.new(["header1", "header2"], ["row3_1", "row3_2"])
table1 == table2 # => false
self[index] -> CSV::Row | [String] | nil[permalink][rdoc][edit]
self[range] -> [CSV::Row]| [Array] | nil
self[header] -> [String] | [nil]

ミックスモードでは、このメソッドは引数に行番号を指定すれば行単位で動作し、ヘッダの名前を指定すれば列単位で動作します。

このメソッドを呼び出す前に CSV::Table#by_col! を呼び出すとカラムモードになります。また CSV::Table#by_row! を呼び出すとロウモードになります。

[PARAM] index:
ミックスモード・ロウモードでは、取得したい行の行番号を整数で指定します。カラムモードでは、取得したい列の列番号を整数で指定します。
[PARAM] range:
取得したい範囲を整数の範囲で指定します。
[PARAM] header:
取得したい列のヘッダを文字列で指定します。ロウモードでは使用できません。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])

# ミックスモード
p table.mode       # => :col_or_row
p table[0]         # => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
p table[1]         # => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
p table["header2"] # => ["row1_2", "row2_2"]
p table[0..1]      # => [#<CSV::Row "header1":"row1_1" "header2":"row1_2">, #<CSV::Row "header1":"row2_1" "header2":"row2_2">]

# カラムモード
table.by_col!
p table.mode       # => :col
p table[0]         # => ["row1_1", "row2_1"]
p table[1]         # => ["row1_2", "row2_2"]
p table["header2"] # => ["row1_2", "row2_2"]
p table[0..1]      # => [["row1_1", "row1_2"], ["row2_1", "row2_2"]]

# ロウモード
table.by_row!
p table.mode       # => :row
p table[0]         # => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
p table[1]         # => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
p table[0..1]      # => [#<CSV::Row "header1":"row1_1" "header2":"row1_2">, #<CSV::Row "header1":"row2_1" "header2":"row2_2">]
self[index_or_header] = value[permalink][rdoc][edit]

ミックスモードでは、このメソッドは引数に行番号を指定すれば行単位で動作し、ヘッダの名前を指定すれば列単位で動作します。

このメソッドを呼び出す前に CSV::Table#by_col! を呼び出すとカラムモードになります。また CSV::Table#by_row! を呼び出すとロウモードになります。

行には配列か CSV::Row のインスタンスを指定します。

列に値を一つだけ指定した場合は、全ての行にその値をコピーします。配列を指定した場合は、上から順に値を割り当てます。余分な値は無視します。また、値が不足している場合は nil を割り当てます。

既存の行または列のデータを上書きします。新しい列を追加する場合は、右端に列を追加します。

[PARAM] index_or_header:
行番号かヘッダの名前を指定します。
[PARAM] value:
値を指定します。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
row3 = CSV::Row.new(["header1", "header2"], ["row3_1", "row3_2"])
table = CSV::Table.new([row1, row2])
table[0] # => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
table[1] # => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
table[1] = row3
table[1] # => #<CSV::Row "header1":"row3_1" "header2":"row3_2">
table.by_col!
table[0] # => ["row1_1", "row3_1"]
table[1] # => ["row1_2", "row3_2"]
table[1] = ["row1_2", "row2_2"]
table[1] # => ["row1_2", "row2_2"]
by_col -> CSV::Table[permalink][rdoc][edit]

カラムモードになっている新しい CSV::Table オブジェクトを返します。

元のテーブルモードを変更せずにメソッドチェーンできるので便利です。しかし、大きなデータセットに対しても同じだけメモリを消費するので気をつけてください。

このメソッドは複製したテーブルを返すので、破壊的なメソッドはメソッドチェーンに組込まないようにしてください。



require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
col_table = table.by_col
col_table[0] # => ["row1_1", "row2_1"]
col_table[1] # => ["row1_2", "row2_2"]
by_col! -> self[permalink][rdoc][edit]

自身をカラムモードに変更します。

再びモードが変更されるまで、いくつかのメソッドはカラム単位で動きます。

[RETURN]
必ず自身を返すので安全にメソッドチェーンできます。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.by_col!
table[0] # => ["row1_1", "row2_1"]
table[1] # => ["row1_2", "row2_2"]
by_col_or_row -> CSV::Table[permalink][rdoc][edit]

ミックスモードになっている新しい CSV::Table オブジェクトを返します。

元のテーブルモードを変更せずにメソッドチェーンできるので便利です。しかし、大きなデータセットに対しても同じだけメモリを消費するので気をつけてください。

このメソッドは複製したテーブルを返すので、破壊的なメソッドはメソッドチェーンに組込まないようにしてください。



require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2]).by_col!
table             # => #<CSV::Table mode:col row_count:3>
col_or_row_table = table.by_col_or_row
col_or_row_table  # => #<CSV::Table mode:col_or_row row_count:3>
table             # => #<CSV::Table mode:col row_count:3>
by_col_or_row! -> self[permalink][rdoc][edit]

自身をミックスモードに変更します。

再びモードが変更されるまで、いくつかのメソッドはミックスモードで動きます。

デフォルトのミックスモードではインデックスによるアクセスは行単位での参照であると見なします。しかし、他の方法ではヘッダによる列単位での参照であると見なします。

[RETURN]
必ず自身を返すので安全にメソッドチェーンできます。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2]).by_col!
table             # => #<CSV::Table mode:col row_count:3>
table.by_col_or_row!
table             # => #<CSV::Table mode:col_or_row row_count:3>
by_row -> CSV::Table[permalink][rdoc][edit]

ロウモードになっている新しい CSV::Table オブジェクトを返します。

元のテーブルモードを変更せずにメソッドチェーンできるので便利です。しかし、大きなデータセットに対しても同じだけメモリを消費するので気をつけてください。

このメソッドは複製したテーブルを返すので、破壊的なメソッドはメソッドチェーンに組込まないようにしてください。



require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table         # => #<CSV::Table mode:col_or_row row_count:3>
row_table = table.by_row  # => #<CSV::Table mode:row row_count:3>
row_table[0] # => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
row_table[1] # => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
by_row! -> self[permalink][rdoc][edit]

自身をロウモードに変更します。

再びモードが変更されるまで、いくつかのメソッドは行単位で動きます。

[RETURN]
必ず自身を返すので安全にメソッドチェーンできます。


require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table         # => #<CSV::Table mode:col_or_row row_count:3>
table.by_row!
table         # => #<CSV::Table mode:row row_count:3>
table[0] # => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
table[1] # => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
delete(index_or_header) -> object[permalink][rdoc][edit]

指定された行か列を削除して返します。

デフォルトのミックスモードではインデックスによるアクセスは行単位での参照であると見なします。しかし、他の方法ではヘッダによる列単位での参照であると見なします。

探索方法を変更したい場合は CSV::Table#by_col!, CSV::Table#by_row! を使用してください。



require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.delete(1)
table.to_a         # => [["header1", "header2"], ["row1_1", "row1_2"]]

[SEE_ALSO] CSV::Table#by_col!, CSV::Table#by_row!, CSV::Table#delete_if

delete_if {|row| ... } -> self[permalink][rdoc][edit]
delete_if {|column_name, values| ... } -> self

ブロックを評価した結果が真である行か列を削除します。

デフォルトのミックスモードかロウモードでは、行単位で繰り返します。カラムモードでは、ブロックに列名と対応する値の配列を与え、列単位で繰り返します。

例 ロウモード

require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "valid"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "invalid"])
row3 = CSV::Row.new(["header1", "header2"], ["row3_1", "valid"])
table = CSV::Table.new([row1, row2, row3])
table.delete_if { |row| row["header2"] == "invalid" }
table.to_a # => [["header1", "header2"], ["row1_1", "valid"], ["row3_1", "valid"]]
例 カラムモード

require "csv"
row1 = CSV::Row.new(["id", "name"], [1, "tanaka"])
row2 = CSV::Row.new(["id", "name"], [2, "suzuki"])
row3 = CSV::Row.new(["id", "name"], [3, "sato"])
table = CSV::Table.new([row1, row2, row3])
table.by_col!
table.delete_if { |column_name, values| column_name == "id" }
table.to_a # => [["name"], ["tanaka"], ["suzuki"], ["sato"]]

[SEE_ALSO] CSV::Table#delete

each {|row| ... } -> self[permalink][rdoc][edit]
each {|column_name, values| ... } -> self

デフォルトのミックスモードかロウモードでは、行単位で繰り返します。カラムモードでは、ブロックに列名と対応する値の配列を与え、列単位で繰り返します。

例 ロウモード

require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
row3 = CSV::Row.new(["header1", "header2"], ["row3_1", "row3_2"])
table = CSV::Table.new([row1, row2, row3])
table.each { |row| p row }

# => #<CSV::Row "header1":"row1_1" "header2":"row1_2">
# => #<CSV::Row "header1":"row2_1" "header2":"row2_2">
# => #<CSV::Row "header1":"row3_1" "header2":"row3_2">
例 カラムモード

require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
row3 = CSV::Row.new(["header1", "header2"], ["row3_1", "row3_2"])
table = CSV::Table.new([row1, row2, row3])
table.by_col!
table.each { |column_name, values| print column_name, values, "\n" }

# => header1["row1_1", "row2_1", "row3_1"]
# => header2["row1_2", "row2_2", "row3_2"]
empty? -> bool[permalink][rdoc][edit]

ヘッダーを除いて、データがないときに true を返します。

Array#empty? に委譲しています。


require 'csv'
csv = CSV.new("a,b\n", headers: true)
table = csv.read
p table.empty?     # => true
table << [1, 2]
p table.empty?     # => false

[SEE_ALSO] Array#empty?

headers -> Array[permalink][rdoc][edit]

自身のヘッダ行を返します。

テーブルが空である場合は空の配列を返します。



require "csv"

row = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
table = CSV::Table.new([row])
table.headers # => ["header1", "header2"]
inspect -> String[permalink][rdoc][edit]

モードとサイズを US-ASCII な文字列で返します。


require 'csv'
csv = CSV.new("a,b,c\n1,2,3", headers: true)
table = csv.read
p table.inspect # => "#<CSV::Table mode:col_or_row row_count:2>"
length -> Integer[permalink][rdoc][edit]
size -> Integer

(ヘッダを除く)行数を返します。

Array#length, Array#size に委譲しています。


require 'csv'
csv = CSV.new("a,b,c\n1,2,3", headers: true)
table = csv.read
p table.size  # => 1

[SEE_ALSO] Array#length, Array#size

mode -> Symbol[permalink][rdoc][edit]

現在のアクセスモードを返します。



require "csv"

row = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
table = CSV::Table.new([row])
table.mode    # => :col_or_row
table.by_col!
table.mode    # => :col
push(*rows) -> self[permalink][rdoc][edit]

複数の行を追加するためのショートカットです。

以下と同じです。


rows.each {|row| self << row }
[PARAM] rows:
CSV::Row のインスタンスか配列を指定します。


require 'csv'
csv = CSV.new("a,b,c\n1,2,3", headers: true)
table = csv.read
rows = [
  CSV::Row.new(table.headers, [4, 5, 6]),
  [7, 8, 9]
]

table.push(*rows)
p table[0..2]
# => [#<CSV::Row "a":"1" "b":"2" "c":"3">, #<CSV::Row "a":4 "b":5 "c":6>, #<CSV::Row "a":7 "b":8 "c":9>]

[SEE_ALSO] CSV::Table#<<

to_a -> [Array][permalink][rdoc][edit]

配列の配列を返します。

一番目の要素はヘッダで、残りの要素はデータを表わします。



require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.to_a # => [["header1", "header2"], ["row1_1", "row1_2"], ["row2_1", "row2_2"]]
to_csv(options = Hash.new) -> String[permalink][rdoc][edit]
to_s(options = Hash.new) -> String

CSV の文字列に変換して返します。

ヘッダを一行目に出力します。その後に残りのデータを出力します。

デフォルトでは、ヘッダを出力します。オプションに :write_headers => false を指定するとヘッダを出力しません。


require 'csv'
csv = CSV.new("a,b,c\n1,2,3", headers: true)
table = csv.read
p table.to_csv                       # => "a,b,c\n1,2,3\n"
p table.to_csv(write_headers: false) # => "1,2,3\n"
values_at(indices_or_headers) -> Array[permalink][rdoc][edit]

デフォルトのミックスモードでは、インデックスのリストを与えると行単位の参照を行い、行の配列を返します。他の方法は列単位の参照と見なします。行単位の参照では、返り値は行ごとの配列を要素に持つ配列です。

探索方法を変更したい場合は CSV::Table#by_col!, CSV::Table#by_row! を使用してください。

アクセスモードを混在させることはできません。

例 ロウモード

require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.values_at(1) # => [#<CSV::Row "header1":"row2_1" "header2":"row2_2">]
例 カラムモード

require "csv"

row1 = CSV::Row.new(["header1", "header2"], ["row1_1", "row1_2"])
row2 = CSV::Row.new(["header1", "header2"], ["row2_1", "row2_2"])
table = CSV::Table.new([row1, row2])
table.by_col!
table.values_at(1) # => [["row1_2"], ["row2_2"]]

[SEE_ALSO] CSV::Table#by_col!, CSV::Table#by_row!

protectedメソッド

table -> Array[permalink][rdoc][edit]

同値性を比較するために内部的に使用します。