
表形式のデータにおいて、列数が行によって可変長となる場合のエレガントな方法を探しています。
■やりたいこと
csv形式の元データを1行可変列に変換し、excelに読み込ませる。
excelに読み込ませるデータをrubyで処理したい。
処理前のデータ
コード、属性ともにユニークではない
コードは数値型、属性は文字型
コード 人数1 人数2 属性
1 1 100 A
2 1 0 B
3 4 1 A
2 5 8 C
4 1 122 D
処理後の最終形態
コードは重複なし。
コード 属性
1 A
2 B,C
3 A
4 D
この処理を
元のデータを1行ずつ読み出す
ハッシュに追加する
ハッシュをcsvに書き出す
と考えて、下記のようなコードを書きましたが、属性部分がカンマで区切られず、配列の値がすべて連結されてしまいます。
■質問
こういうデータを処理するときにどうすればいいか?
(後学のために、なぜそうしたほうがよいのかを教えていただけると幸いです)
具体的にこのコードを書き直すとしたら、どこをどう変更すればよいか?
いろいろなリファレンスを読んだのですが、列数が可変長となる場合のサンプルが見つけられなくて詰まってしまいました。
よろしくお願いいたします。
環境:active ruby 1.8.6 , windows XP SP3 ,
■作成したコード(抜粋)
require 'csv'
in_path='C:\Documents and Settings\a\デスクトップ\解凍後データ\dummy.txt'
out_path='C:\Documents and Settings\a\デスクトップ\解凍後データ\out.txt'
#set initial values
col_code=0 'コード列位置
col_zokusei=3 '属性列位置
h=Hash.new{|h,key| h[key]=[]}
CSV.foreach(in_path){|row|
h[row[col_code]]<<row[col_zokusei]
}
#put hash to csv file.
CSV.generate(out_path){ |writer|
h.to_a.each{ |row|
p row
writer << row
}
}
No.2ベストアンサー
- 回答日時:
何故そうなるかは、["2",["B","C"]] というデータをCSV出力しようとするので、1項目が"2"でこれは文字列でそのままOK。
2項目は["B","C"]で文字列でなく配列なので、["B","C"].to_s で文字列化されます。この結果は"BC"になります。2,B,Cと出力したければ、#1の方の回答の通り、["2",["B","C"]].flatternで、["2","B","C"]に変換して出力するといいかと。
2,"B,C"にしたいとか、もっと全体をすっきりさせたいとすると、属性保存の所で、配列を借用するのじゃなくて自分でクラスを定義して、to_sも定義します。
require 'csv'
in_path=・・・・・
out_path=・・・・・
class Attr
def initialize; @data = []; end
def <<(other); @data |= [other]; end # 集合の和集合(重複を省く)
def to_s; @data.join(","); end
end
h=Hash.new{|h,key| h[key]=Attr.new}
CSV.foreach(in_path){|key,n1,n2,attr|
h[key.data.to_i] << attr.data
}
CSV.generate(out_path){ |writer|
h.sort.each{ |row| #ソートした方が良いかと
writer << row
}
}
解説ありがとうございました。
flattenメソッドの意味が分かりました。
rubyリファレンスマニュアルを読むと、確かに書いてありますね。
「ネストした配列を平滑化してそれを返します。」ってそういう意味か~と納得しました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Ruby require ライブラリー
-
ruby loopメソッド 変数(再喝)
-
英数字を含む文字列(0-9,A-Z)...
-
ruby OpenURI::Meta
-
ruby while式
-
100万件越えCSVから条件を満た...
-
ルビー言語 csvファイル part2
-
WinSCPで画像のように puttyを...
-
パソコンのスクリーンセーバー...
-
教えてください
-
実行時エラー450:引数の数が一...
-
(再質問)エクセルのマクロボ...
-
ruby loopメソッド 変数
-
ルビー言語 csvファイル 続き
-
Ruby newメソッド
-
1、Rstudioで回帰直線を求める...
-
符号付整数の演算結果を答えよ ...
-
ruby 配列
-
ruby クラス・オブジェクト・イ...
-
ルビー言語 ライブラリー 追記
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excelマクロ 空白セルを無視し...
-
VBAでcsvファイルもシートもあ...
-
ダブルコーテーション付きでCSV...
-
【ExcelVBA】300万件越えCSVか...
-
ファイル名を変数で書きこむfwr...
-
VBAで複数のCSVからレコードセ...
-
CSVで余計な空行が入る
-
複数のファイルをまたぐエクセ...
-
VB.netでShellExecuteがしたい
-
LibreOffice Calcのマクロで、...
-
【C#】 csvファイルをバイナリ...
-
pythonでリストをCSVに出力する...
-
EXCEL→CSV保存時のダブルクォー...
-
PYthon Django csv関連
-
pythonについて質問です。 csv...
-
マクロで使うfor文
-
プログラムの間違いについて
-
Pythonのコードエラーについて...
-
Rubyを使用してcsvファイルを処...
-
CSVデータの文字列置換
おすすめ情報