質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

5回答

2447閲覧

テキストファイルの内容を指定数行分ごとに一行に連結を繰り返すには

LIATARET

総合スコア17

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2016/04/17 11:43

以下のような内容のテキストファイルを読み込んで、
1A
2A
3A
1B
2B
3B
1C
2C
3C
.
.
.

このように3行ごとに1行に連結を繰り返して書き換えたいのですが、どうしたら良いでしょうか。
1A, 2A, 3A
1B, 2B, 3B
1C, 2C, 3C
.
.
.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

each_slice をつかって書いてみました。
(入力行数が 3 の倍数で無かった場合の挙動を他の回答と比べてみてほしいです)

a.rb

ruby

1lines = IO.readlines('data.txt').map(&:chomp) 2 3lines.each_slice(3) do |arr| 4 puts arr.join(',') 5end

実行例

$ cat data.txt 1A 2A 3A 1B 2B 3B 1C 2C $ ruby a.rb 1A,2A,3A 1B,2B,3B 1C,2C

投稿2016/04/17 22:10

編集2016/04/18 14:12
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LIATARET

2016/04/18 04:50

回答ありがとうございます。 短くて分かりやすいですね。 勉強になります。
guest

0

もうちょっとエレガントに書けそうな気がしますが、とりあえず。

Ruby

1data = IO.readlines("datafile").map(&:chomp) 2 3n=-1 4join_3lines = data.chunk{n+=1; n/3}.map{|k,v| v.join(",")} 5 6puts join_3lines

投稿2016/04/17 12:07

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LIATARET

2016/04/17 13:28

回答ありがとうございます。 おかげさまで希望通りに書き換えることが出来ました。 コードが短くてかっこいいですね。 内容を理解したいと思います。
guest

0

#基本的なロジックとして

行が3の倍数だったら、そのまま出力(print)
それ以外なら、改行をとってカンマを付与してprint

投稿2016/04/17 13:12

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ベタなやり方ですが、ご参考まで。

ruby

1# coding: utf-8 2 3begin 4 File.open('input.txt') do |file| 5 6 line_count = 0 # 読み込み中の行番号 7 three_items = '' # 連結した文字列を作る変数 8 9 file.each_line do |line| 10 line.chomp! 11 break if line.length == 0 12 13 line_count +=1 # 行番号をインクリメント 14 15 three_items += line 16 17 if line_count % 3 == 0 then # 行番号が3で割り切れる場合 18 puts three_items # 連結した文字列を表示 19 three_items = '' # 連結した文字列を空にする。 20 else 21 three_items += ',' # 行番号が3で割り切れない場合、まだ後に連結するのでカンマを追加 22 end 23 24 end 25 end 26rescue SystemCallError => e 27 puts %Q(class=[#{e.class}] message=[#{e.message}]) 28rescue IOError => e 29 puts %Q(class=[#{e.class}] message=[#{e.message}]) 30end

上記を、tera32595.ruby で保存し、入力ファイルは input.txt で作成しておき、
実行してみたのが以下です。

[ykt68@MacMini teratail]$ date

2016年 4月17日 日曜日 21時45分22秒 JST
[ykt68@MacMini teratail]$ cat input.txt
1A
2A
3A
1B
2B
3B
1C
2C
3C
[ykt68@MacMini teratail]$ ruby tera32595.ruby
1A,2A,3A
1B,2B,3B
1C,2C,3C
[ykt68@MacMini teratail]$

投稿2016/04/17 12:49

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LIATARET

2016/04/17 13:30

回答ありがとうございます。 おかげさまで希望通りに書き換えることが出来ました。 理解しやすく助かりました。
guest

0

処理の順番を書きます。

1・インデックスiを初期化
2・文字列バッファをクリア
3・インデックスiをインクリメント
4・文字列バッファに区切り文字、次の文字列を連結
5・もしインデックスが3なら1へ、そうではなければ6へ続行
6・文字列バッファから最後の1文字(区切り文字)を削除して出力
7・3へ戻る

変なネストになるかもしれないので適宜インデックスと文字列バッファの初期化の位置を工夫してください。

投稿2016/04/17 12:12

yosatonet

総合スコア46

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問