2017-04-21 3 views
1

は、私は、ファイルルビー - 数値化ファイルを読む

a_1, a_2, ..., a_n 
b_1, b_2, ..., b_n 

の束を持って想像して、私のスクリプトは次の順序でファイルを読み込む必要があります:

a_1, b_1, a_2, b_2, ..., a_n, b_n 

私は時にファイルを読み取る方法を知っています名前が指定されています。すなわちFile.open("a_1.txt", "r")、私はちょうど私がこのような何かをするだろう

while i < n 
    File.open("a_i.txt", "r") 
    do sth 
end 
+0

あなたは 'File.open( "_#{I} .TXT"、 "R")'のようなものが必要なのでしょうか? 'i'は変更されますが、ファイル名も変更され、新しい繰り返しごとに新しいファイルを読み込むことができます。このスニペットを確認してください - https://repl.it/HTfV – marmeladze

+0

@marmeladzeこれは 'a_1.txt'、' a_2.txt'、 'a_3.txt'などを開きますが、OPは' a_1.txt'、 b_1.txt'、 'a_2.txt'、' b_2.txt'、... – Stefan

答えて

1

ようになりますループを持っているように、私は名前を指定することができます。

5はあなたの nに置き換える必要があります
file_names = (1..5).to_a.product(%w[a b]).map { |(a, b)| "#{b}_#{a}.txt" } 

file_names.each do |file_name| 
    # File.open(file_name, 'r') 
end 

を。

それとも、ネストされたループを使用することがあります:

(1..5).each do |n| 
    %w[a b].each do |c| 
    # File.open("#{c}_#{n}.txt", 'r') 
    end 
end 
+0

ファイルに 'n'という数字を付けることができます。ファイルの一部が欠落しているとエラーが発生する可能性があります。 OPの要件に応じて –

-1

必要なコードは次のとおりです。あなたが "#{expr}が" 内部を入れ、文字列、値で

while i < n 
    File.open("a_#{i}.txt", "r") { |file| 
     do sth 
    } 
end 

exprの実行時に評価され、埋められます。 例:

>irb 
irb(main):001:0> i = 5 
=> 5 
irb(main):002:0> "a_#{i}" 
=> "a_5" 
1

あなたはファイルがあることを行っている正確に何を事前に知っていない場合は、ディレクトリリストをソートすることもできます。

files = Dir["/path/to/files/*.txt"].sort_by{|f| [f[\d+].to_i, f]} 
#=> ["a_1.txt", "b_1.txt", "a_2.txt", "b_2.txt", ...] 

これは、ファイル名の番号順、次に名前自体によってソートされます。次に、それらを配列順に開きます。

+0

おそらく、番号と文字の両方でソートする必要があります。 – Stefan

+0

@Stefanそれは良い点です。 'Dir'はアスキー値でそれらをソートしますが、sort_byがそれを保持することは保証されていないと思います。 –

+0

私はあなたの最初の行を私の答えにコピーしました;) –

0
> files = Dir["/path/to/files/*.txt"] 
#=> ["a_5", "b_2", "b_9", "b_1", "b_10", "b_3", "b_5", "b_8", "a_1", "a_3", "a_8", "a_6", "a_2", "a_7", "b_6", "b_7", "b_4", "a_10", "a_4", "a_9"] 
> files_in_order = files.group_by{|e| e.split("_").last.to_i}.sort.map{|v| v[1].sort}.flatten 
#=> ["a_1", "b_1", "a_2", "b_2", "a_3", "b_3", "a_4", "b_4", "a_5", "b_5", "a_6", "b_6", "a_7", "b_7", "a_8", "b_8", "a_9", "b_9", "a_10", "b_10"] 
+1

2番目の答えは整数でのみソートされます。 –

3

あなたは[number, letter]によって周り_とソートを分割し、ファイルのベース名を得ることができます:

# filenames = Dir.glob('input/*') 
filenames = ["input/a_6", "input/b_8", "input/b_7", "input/a_3", "input/a_4", "input/b_4", "input/b_9", "input/b_1", "input/b_11", "input/a_11", "input/b_3", "input/b_2", "input/a_1", "input/b_6", "input/b_12", "input/a_8", "input/a_2", "input/a_9", "input/a_5", "input/b_10", "input/a_7", "input/b_5", "input/a_10", "input/a_12"] 

filenames.sort_by! do |filename| 
    letter, number = File.basename(filename).split('_') 
    [number.to_i, letter] 
end 

p filenames 
# ["input/a_1", "input/b_1", "input/a_2", "input/b_2", "input/a_3", "input/b_3", "input/a_4", "input/b_4", "input/a_5", "input/b_5", "input/a_6", "input/b_6", "input/a_7", "input/b_7", "input/a_8", "input/b_8", "input/a_9", "input/b_9", "input/a_10", "input/b_10", "input/a_11", "input/b_11", "input/a_12", "input/b_12"] 

私は通常、異なるフォルダに入力ファイルやスクリプトを置くのが好き。

最後に、"3".to_i"3.txt".to_iは両方とも3を返すので、このコードは任意の拡張子(拡張子を含まない)で動作するはずです。明示的なソートなし

ただ、好奇心のうち
+0

OPの例には拡張子「.txt」があります。 –

+0

@MarkThomas:OPの例の半分に '.txt'拡張子があります。 '' 3.txt ".to_i"は依然として '3'なので、このコードはどんな拡張子でも動作するはずです。 –

+0

'to_i'は本当に気にしませんが、明示的にしたいと思っていれば:' File.basename(filename、 '.txt') ' – Stefan

0

、 :

Dir["/path/to/files/*.txt"].chunk { |e| e.split("_").first } 
          .map(&:last) 
          .reduce(&:zip) 
          .flatten 
+0

配列をソートせず、いくつかの有効なファイル名を削除し、 'nil'を導入するかもしれません。何が好きではないですか? :) –

+0

@EricDuminil私は何かが削除されている理由はわかりませんが、ソートは暗黙のうちに 'Dir#[]'によって行われると思います。 – mudasobwa

+0

'%w(a_1 a_2 b_1 b_2 b_3)' –