1

先に進む前に、ユーザーが「sakai_trained」配列に含まれているかどうかを確認するコードが少しあります。何らかの理由で、このコードを実行すると:

CSV.foreach(activation_csv, {:headers => true}) do |row|
  if sakai_trained
    row << 'Untrained' unless sakai_trained.include?(row[1]) 
  end
  
  course_list << row
end

このエラーが発生します

C:/Ruby193/lib/ruby/1.9.1/csv.rb:478:in `==': undefined method `row' for "stuartademo":String (NoMethodError)
        from activate-courses.rb:42:in `include?'
        from activate-courses.rb:42:in `block in <main>'
        from C:/Ruby193/lib/ruby/1.9.1/csv.rb:1792:in `each'
        from C:/Ruby193/lib/ruby/1.9.1/csv.rb:1208:in `block in foreach'
        from C:/Ruby193/lib/ruby/1.9.1/csv.rb:1354:in `open'
        from C:/Ruby193/lib/ruby/1.9.1/csv.rb:1207:in `foreach'
        from activate-courses.rb:40:in `<main>'

最初はrow[1]に問題があると思っていましたが、文字列リテラルでも同じように壊れます。sakai_trained 配列が存在し、データも含まれていることを確認しました。また、unless ロジックに欠陥がある場合に備えて、if ステートメントとして書き直そうとしましたが、それでも同じエラーが返されます。

不明な場合は、行を course_list 配列に追加する前に、行 [1] にあるユーザー ID が sakai_trained 配列に存在することを確認したいと思います。そうでない場合は、最初に「Untrained」を行に追加してから、行を配列に追加します。until... 部分を削除すると、完全な course_list 配列を取得できましたが、予想どおり、すべての行が「訓練されていない」ものです。問題は

unless sakai_trained.include?(row[1])

一部ですが、見えません。

アップデート:

sakai_trained = []
  CSV.foreach(training_csv, {:headers => true}) do |trained|
    sakai_trained << trained
  end

#map するべきか!.to_s を使用して各アイテムを文字列にしますか?

更新 2:

私が変更され

sakai_trained << trained

sakai_trained << trained.to_s

エラーは削除されましたが、出力はまだ正しくありません。

更新 3: ほぼ。働く。皆さんは信じられないほど素晴らしく、これと同じくらいイライラしますが、私はいくつかの新しく興味深いことを学びました.

コード:

course_list = []

if options[:verify]
  sakai_trained = []
  CSV.foreach(training_csv, {:headers => true}) do |trained|
    sakai_trained << trained.to_s
  end
end 
 
CSV.foreach(activation_csv, {:headers => true}) do |row|
  if sakai_trained && !sakai_trained.include?(row[1])  
    row << 'Untrained' 
  end
  
  course_list << row
end

収量:

2124-5318、stuartademo、訓練を受けていない

2124-5320、ボブスミス、訓練を受けていない

2124-4686、ジムスミス、訓練を受けていない

2124-3560、ジルスミス、訓練を受けていない

2124-3562、スースミス、訓練を受けていない

2124-5428、ハリースミス、訓練を受けていない

あるべきとき

2124-5318、stuartademo、訓練を受けていない

2124-5320、ボブスミス

2124-4686、ジムスミス

2124-3560、ジルスミス

2124-3562、スースミス

2124-5428、ハリースミス

4

2 に答える 2

2

この問題はcsv.rb、標準 Ruby ライブラリの 478 行目のファイル内で発生しています。CSV問題の原因となっているコードは次のとおりです。

#
# Returns +true+ if this row contains the same headers and fields in the
# same order as +other+.
#
def ==(other)
  @row == other.row
end

エラー メッセージの外観から、文字列"stuartademo"がこのメソッドに渡されており、もちろん、String#row. othercsvファイルの行であるように見えます。上記のメソッドに関するコメントによると、ヘッダーとフィールドを含める必要があります。

この文字列がどこから来ているのかを見つけ、"stuartademo"行全体ではなく文字列のみが渡される理由を突き止めることをお勧めします。

編集:

が CSV から取り込まれた場合sakai_trained、それは配列ではなくCSV:Row型です。この場合、呼び出すとCSV::Row#include?==(other)が呼び出されます。したがって、渡しているのはrow[1]文字列です。文字列であってはなりません。

を使用する代わりに、またはを使用include?してみてください。field?(data)fields.include?

CSV.foreach(activation_csv, {:headers => true}) do |row|
  if sakai_trained
    row << 'Untrained' unless sakai_trained.field?(row[1]) 
  end

  course_list << row
end
于 2012-04-20T18:43:28.463 に答える
1

これによりロジックが少し単純化され、別の方法で問題を追跡するのに役立つと思います。

CSV.foreach(activation_csv, {:headers => true}) do |row|
  if sakai_trained && !sakai_trained.include?(row[1])
    row << 'Untrained'
  end

  course_list << row
end

アップデート:

それをいくつかの部分に分解して、すべての出力が何であるかをお知らせください。

CSV.foreach(activation_csv, {:headers => true}) do |row|
  puts row                   #=>  2124-5318,stuartademo
  puts row.class             #=>  CSV::Row 
  puts row[1]                #=>  stuartademo 
  puts row[1].class          #=>  String 
  puts sakai_trained         #=>  I'm assuming nil because it is of NilClass
  puts sakai_trained.class   #=>  NilClass
end

あなたの sakai_trained は実際にエラーを取り除くnil理由を説明していると思います。nil をsakai_trained.to_s呼び出すことはできませんが、使用すると、おそらくfalse を返すに変わります。include?to_s""

于 2012-04-20T19:32:53.650 に答える