
表形式のデータにおいて、列数が行によって可変長となる場合のエレガントな方法を探しています。
■やりたいこと
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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- Visual Basic(VBA) コード名シートA列と集計シートA列のコードが一致したら、コード名シートA5からk12の範囲をコピーし 1 2022/08/29 23:46
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでcsvファイルもシートもあ...
-
ダブルコーテーション付きでCSV...
-
【ExcelVBA】300万件越えCSVか...
-
バッチファイルで複数のディレ...
-
Excelマクロ 空白セルを無視し...
-
LibreOffice Calcのマクロで、...
-
マクロで使うfor文
-
文字列の結合がうまくいかない
-
エクセルの任意のシートをcs...
-
Sikulix2.0.5(Jython2.7.3)でcs...
-
VBAで複数のCSVからレコードセ...
-
ファイル名を変数で書きこむfwr...
-
複数のファイルをまたぐエクセ...
-
バッチ処理 特定の文字以降を...
-
シュラフを圧縮袋へ
-
[Excel VBA] 入力された値に応じて
-
フォーム間でtxtbox値の渡しで...
-
[コンパイルエラー 修飾子が不...
-
pycharmへのpysamインストール...
-
SQLでテキストボックスの文字を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでcsvファイルもシートもあ...
-
Excelマクロ 空白セルを無視し...
-
【ExcelVBA】300万件越えCSVか...
-
ダブルコーテーション付きでCSV...
-
ファイル名を変数で書きこむfwr...
-
VBAで複数のCSVからレコードセ...
-
CSVデータの文字列置換
-
複数のファイルをまたぐエクセ...
-
CSVファイルの比較と結果の取得...
-
【C#】 csvファイルをバイナリ...
-
PowerShellからGhostscriptを動...
-
EXCEL→CSV保存時のダブルクォー...
-
VB.NETでオブジェクトの内容を...
-
パイソン文法で ファイルオープ...
-
VB.netでShellExecuteがしたい
-
PowerShellでファイルの連結方法
-
Rubyを使用してcsvファイルを処...
-
rubyを用いたCSVファイルの分割...
-
バッチファイルでcsvファイルに...
-
エクセルの任意のシートをcs...
おすすめ情報