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

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

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

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

Ruby on Rails 3

Ruby on Rails3はRubyによって書かれたオープンソースのウェブフレームワークです。Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

3回答

2302閲覧

HashとArrayの使い方がわからず悩んでいます...

fujimaru

総合スコア16

Ruby

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

Ruby on Rails 3

Ruby on Rails3はRubyによって書かれたオープンソースのウェブフレームワークです。Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

2グッド

1クリップ

投稿2016/01/25 11:42

編集2016/01/25 12:16

Ruby on Railsを先週から勉強はじめました。
以下のコードでわからないとこがあるので教えて下さい...。宜しくお願いします。

①『item.csv』というcvsデータを読み込む。
→csvデータの中には【商品コード】【商品名】【金額】が書いている。

※csvデータ A1,たい焼き,500 A2,たこ焼き,300 A3,やきとり,100 B1,ビール,600 B2,焼きそば,300

②コマンドライン引数で、【商品コード】とマッチしていれば、以下のように表示する。

※実行結果【理想】 ruby Cart.rb A1 A2 A5 B2 → 【商品コード】A1【商品名】たい焼き【金額】500円 【商品コード】A2【商品名】たこ焼き【金額】300円 商品がありません。 【商品コード】B2【商品名】ビール【金額】600円

とコマンドライン引数の要素を一つづつ判別して、trueかfalseか調べたいのですが、実行すると、

※実行結果【現実】 ruby Cart.rb A1 A5 → [商品コード] A1 [商品名] たい焼き [金額] 500円 商品がありません。 商品がありません。 商品がありません。 商品がありません。 商品がありません。 商品がありません。 商品がありません。 商品がありません。 商品がありません。

と表示されてしまいます。readFileの中でループ処理を2回しているのが原因だと思うんですが、
その解決がわからないので、もしわかればおしえていただきたいです。
宜しくお願いします。

ITEM = "item.csv" class Cart def initialize(code,name,value) @code = code @name = name @value = value end def toString return "[商品コード] #{@code} [商品名] #{@name} [金額] #{@value}円" end end def readFile goods = File.read(ITEM) goods.each_line do |line| good = line.split(",") cart = Cart.new(good[0],good[1],good[2]) for i in 0..ARGV.length hash = {good[0] => cart.toString()} if ARGV[i] == good[0] puts hash[ARGV[i]] else puts "商品がありません。" end end end end def exec readFile() end exec()

コードが読みにくいかもしれませんが、よろしくお願いします。

ikuwow👍を押しています

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

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

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

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

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

iwamoto_takaaki

2016/01/25 11:53

実行してみて調べる回答者のために item.csv の中身と、入力したコマンドラインも載せてください。 ちなみにコードやファイルの行頭と行末を「’’’」で囲むとコードが四角く囲まれ読みやすくなります。
fujimaru

2016/01/25 12:01

ご指摘ありがとうございました。変更いたしました。引き続きお願いします。
guest

回答3

0

ベストアンサー

「コマンドライン引数1つずつに対して、ファイルにあるかどうか調べる」
じゃなくて、
「ファイルの1行ずつについて、コマンドライン引数にあるかどうか調べる」
になっているので、表示される結果はファイルの行数と同じになります。コマンドラインにないファイルの行については、「商品がありません。」と出ます。

という説明で分かりますでしょうか?

投稿2016/01/25 11:59

otn

総合スコア84505

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

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

0

fujimaru さんの回答コードを少し書きなおしてみました。
ccc.rb

ruby

1class Goods 2 ITEM_FILE = 'item.csv' 3 4 def read_csv 5 csv = [] 6 File.read(ITEM_FILE).each_line do |line| 7 csv << line.chop.split(',') 8 end 9 csv # 配列 10 end 11 12 def items_hash 13 hash = {} 14 csv = read_csv 15 # 配列からハッシュを作る 16 csv.each do |line| 17 hash[line[0]] = { name: line[1], price: line[2].to_i } 18 end 19 hash 20 end 21 22 def exec(argv) 23 hash = items_hash 24 argv.each do |code| 25 data = hash[code] 26 if data 27 puts "【商品コード】#{code} 【商品名】#{data[:name]} 【金額】#{data[:price]}" 28 else 29 puts "商品がありません。(#{code})" 30 end 31 end 32 end 33end 34 35goods = Goods.new 36goods.exec(ARGV)

実行結果

$ ruby ccc.rb A1 A2 A5 B2 【商品コード】A1 【商品名】たい焼き 【金額】500 【商品コード】A2 【商品名】たこ焼き 【金額】300 商品がありません。(A5) 【商品コード】B2 【商品名】焼きそば 【金額】300

投稿2016/01/30 22:32

katoy

総合スコア22324

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

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

fujimaru

2016/01/31 13:27

お!なるほど!僕は普段Javaを使っているのでJava的なコードになってしまうんですが、こんな書き方もあるんですね。とても参考になりました。ありがとうございます!
fujimaru

2016/01/31 13:40 編集

hash = items_hash argv.each do |code| data = hash[code] if data puts "【商品コード】#{code} 【商品名】#{data[:name]} 【金額】#{data[:price]}" else puts "商品がありません。(#{code})" end ここの部分は data = nil => else という分岐になるんですか?
katoy

2016/01/31 13:52

if data は if data != nil としてもよいです。
katoy

2016/01/31 15:10 編集

もっと ruby らしく書くことは可能です。 いろいろな書き方を考えてみるとよいと思います。
guest

0

以下のコードで解決できました。

やはりfor文を2回回していた箇所でエラーが出ていたので、
for文を分割して処理しました。

class Cart def initialize(code,name,capa) @code = code @name = name @capa = capa end def toString return "[商品コード] #{@code} [商品名] #{@name} [金額] #{@value}円" end end class Goods Item = "item.csv" def readFile result = [] goods = File.read(ITEM) goods.each_line do |line| good = line.split(",") ware = Cart.new(good[0],good[1],good[2]) result << ware.toString end return result end def readCode code = [] goods = File.read(ITEM) goods.each_line do |line| good = line.split(",") code << good[0] end return code end def getHash hash = {} for i in 0..readCode().length hash.store(readCode()[i], readFile()[i]) end return hash end def argv for i in 0..ARGV.length-1 if getHash()[ARGV[i]] != nil puts getHash()[ARGV[i]] else puts "商品がありません。" end end end def exec argv() end goods = Goods.new() goods.exec() end

投稿2016/01/30 12:22

編集2016/01/31 13:24
fujimaru

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問