データベースとCSVの相互変換

 2011-08-07
データベースとCSVの相互変換についてちょっと試してみました。

[追記] データベースとCSVの相互変換(2)

適当にメソッドの定義を行います。
データベースを CSV ファイルに変換する処理と
# データベースの書き出し
def save_csv(filename, data, methods)
File.open(filename, "w") do |file|
file.write(
data.map {|o| methods.map {|m| o.__send__(m) }.join(",") }.join("\n"))
end
end
CSV ファイルを RVDATA ファイルに変換する処理です。
# CSV ファイルからデータの読み込み
def load_csv(data, methods)
methods.each do |fn, ms|
File.open(fn, "r") do |f|
f.readlines.each_with_index do |s,i|
csv = s.chomp.split(",")
for j in 0...ms.size
data[i].instance_variable_set("@#{ms[j]}", convert(csv[j]))
end
end
end
end
end
# CSV ファイルから配列の読み込み
def load_array(data, methods)
methods.each do |fn, ms|
File.open(fn, "r") do |f|
f.readlines.each_with_index do |s,i|
for m in ms
for v in s.chomp.split(",")
data[i].instance_eval("@#{m} << #{convert(v)}")
end
end
end
end
end
end
# CSV ファイルから Table の読み込み
def load_table(data, methods)
methods.each do |fn, ms|
File.open(fn, "r") do |f|
f.readlines.each_with_index do |s,i|
csv = s.chomp.split(",")
ms.each {|m| csv.size.times {|j| data[i].__send__(m)[j] = csv[j] } }
end
end
end
end
# 文字列を変換
def convert(value)
return true if value == "true"
return false if value == "false"
return value.to_i if value[/^\d+$/]
return value
end

今回は、項目の少ない武器のデータを変換してみます。
まず、入出力するプロパティを定義します。
配列の場合は、別のファイルに分けるために定義も別にします。
データ構造については、ヘルプに載っています。
# プロパティの定義
weapons = [ :id, :name, :icon_index, :description, :note,
:animation_id, :price, :hit, :atk, :def, :spi, :agi,
:two_handed, :fast_attack, :dual_attack, :critical_bonus ]
element_set = [:element_set]
state_set = [:state_set]

データベースの情報をCSVに書き出すには以下のようにします。
データベースの情報には、nil が含まれているので、それを削除したものを
先ほど定義したメソッドに渡します。
save_csv(ファイル名, データ, 書き出すメソッド) となってます。
# データベースの読み込み
data = load_data("Data/Weapons.rvdata").compact
# ファイルに書き出す
save_csv("Weapons.csv", data, weapons)
save_csv("ElementSet.csv", data, element_set)
save_csv("StateSet.csv", data, state_set)

そのファイルから RVDATA ファイルを作るには、以下のようにします。
まず、武器の数だけ初期値のデータ作成します。
あとは、load_xxxx を使って、この初期データを変更していきます。
最後に save_data を使って、RVDATA を作成すれば、
Data フォルダ内のファイルと置き換えられる形式のファイルが作成されます。
# RVDATA ファイルに変換
data = Array.new(30) { RPG::Weapon.new }
load_csv(data, {"Weapons.csv" => weapons})
load_array(data, {"ElementSet.csv" => element_set,"StateSet.csv" => state_set})
save_data([nil] + data, "Weapons.rvdata")

こんな感じにすると、うまくいったっぽい。
あと、load_table あるのに、よく見ると save_csv が Table に対応していないのとかはご愛嬌。

[おまけ]
アイテムもちょっと試してみた。
base_item = [:id, :name, :icon_index, :description, :note]
usable_item = [ :scope, :occasion, :speed, :animation_id, :common_event_id,
:base_damage, :variance, :atk_f, :spi_f, :physical_attack,
:damage_to_mp, :absorb_damage, :ignore_defense ]
item = [:price, :consumable, :hp_recovery_rate, :hp_recovery,
:mp_recovery_rate, :mp_recovery, :parameter_type, :parameter_points]
element_set = [:element_set]
plus_state_set = [:plus_state_set]
minus_state_set = [:minus_state_set]
data = load_data("Data/Items.rvdata").compact
save_csv("Items.csv", data, base_item + usable_item + item)
save_csv("ElementSet.csv", data, element_set)
save_csv("PlusStateSet.csv", data, plus_state_set)
save_csv("MinusStateSet.csv", data, minus_state_set)
data = Array.new(20) { RPG::Item.new }
load_csv(data, {"Items.csv" => base_item + usable_item + item})
load_array(data, { "ElementSet.csv" => element_set,
"PlusStateSet.csv" => plus_state_set,
"MinusStateSet.csv" => minus_state_set })
save_data([nil] + data, "Items.rvdata")

アイテム系は、すべて処理できそうだね。
コメント




 

 ※ コメント内にURLを含めるには、バッククォート(`)をURLの直前に付け加えてください。


管理人のみ閲覧許可 [?]

トラックバック
トラックバックURL:
http://cacaosoft.blog42.fc2.com/tb.php/564-57177bfc
≪ トップページへこのページの先頭へ  ≫
カレンダー
01 << 2017/03 >> 02
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

カテゴリー
最近の記事
02/28 お返事
02/14 お返事
01/21 お返事
01/12 更新情報
11/28 お返事

最近のコメント
03/16 お返事
01/21 お返事
11/30 z座標
11/20 z座標
08/03 お返事

タグクラウド

リンク