Rubyで必要な行だけファイルから取り出して複数行のソートするクラス作ってみた.
友人からの頼まれごと
かなりコアな題材で物理演算を行なっている友人がいて,その方からの頼まれごとで作って見ました.ご飯でもご馳走してもらおうかな
依頼内容
大まかに2つありました.
- 計算機から複数のデータが羅列された一つのファイルが出力されるから,必要な分だけ取り出したい.
- ファイルのソートを優先順位をつけて行いたい.
要は
-5.00 -4.00 9.77394 5.48712 3.61496 -57.3331870000 +1.0091838809
-2.00 -1.00 10.08259 5.65860 3.61496 -57.4409550000 +0.9363980334
-2.00 +1.00 10.08259 5.77291 3.61496 -57.3427100000 +0.9555686992
-3.00 -3.00 9.97971 5.54428 3.61496 -57.4680020000 +0.9448945625
-5.00 +0.00 9.77394 5.71575 3.61496 -57.4110870000 +0.9386141037
+0.00 +0.00 10.28836 5.71575 3.61496 -57.2935550000 +0.9841821532
-2.00 +0.00 10.08259 5.71575 3.61496 -57.3990650000 +0.9432751244
これのもっと長いファイルが計算機から出力されるから
-5.0 -4.0 -57.333187
-5.0 -3.0 -57.377965
-5.0 -2.0 -57.405772
-5.0 -1.0 -57.41669
-5.0 +0.0 -57.411087
-5.0 +1.0 -57.389966
-4.0 -4.0 -57.404478
-4.0 -3.0 -57.434789
-4.0 -2.0 -57.449075
みたいな感じで綺麗にしていってよってお話です.
実装
コードをぺたり
require "fileutils"
class SortSlabData
def initialize
end
# get necessary lines from the file
def need_lines(file, need_lines)
new_lines = []
File.open(file, "r+") do |file|
file.each_line do |f|
items = f.split
items.clone.each_with_index.reverse_each do |line, index|
items.delete_at(index) unless need_lines.include?(index)
end
new_lines << items.join(" ")
end
end
new_lines
end
def sort_lines(lines, sort_lines)
lines = lines.clone
lines.clone.each_with_index do |line, index|
lines[index] = all_to_f(line.split)
end
lines.sort_by! do |x|
sort_items = []
sort_lines.each do |line|
sort_items << x[line]
end
sort_items
end
lines
end
# write_linesは指定の書式があったのでそれを遵守した書き方になっています.ここは万人向けではないので無視していいでしょう.
def write_lines(file, lines)
contents = []
File.open(file, "w+") do |file|
min = -(10**7)
# format_arrangement
lines.each do |line|
if min < line[0]
min = line[0]
contents << "\n"
end
line.each_with_index do |item, index|
line[index] = item.to_s
line[index].insert(0, '+') if line[index][0] != '-'
end
contents << line.join(" ")
end
contents.shift if contents[0] == "\n"
# file_write
contents.each do |content|
file.puts(content)
end
end
end
private
def all_to_f(objs)
objs.each_with_index do |obj, index|
objs[index] = obj.to_f
end
objs
end
end
# make x, y, energy file
file_path = ARGV[0]
physics_sort = SortSlabData.new
lines = physics_sort.need_lines(file_path, [0, 1, 5])
sorted_lines = physics_sort.sort_lines(lines, [0, 1])
physics_sort.write_lines("xy_E_#{file_path}", sorted_lines)
ファイルから必要な行だけ取り出して配列に入れる.
def need_lines(file, need_lines)
で行なっています.
引数で与えらたfile
には抜き出すファイルを指定.need_lines
には配列で抜き出したい列番号を指定.
ex) file = 'datas.txt', need_lines = [0, 1, 5]
配列のソートを優先順位をつけて行う.
def sort_lines(lines, sort_lines)
で行なっています.
引数で与えらたlines
にはソートする配列を指定.sort_lines
には優先する順に要素番号を記入した配列を記載.
ex) lines = ["0 4 5", "8 9 10"], need_lines = [0, 1]
まとめ
結構限定的なお話なのでほとんどの人には参考にならないでしょうが,一応記事にまとめておきました.
Author And Source
この問題について(Rubyで必要な行だけファイルから取り出して複数行のソートするクラス作ってみた.), 我々は、より多くの情報をここで見つけました https://qiita.com/TurkeyLeg0403/items/68dbe26dc89d1e3ba965著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .