CSV验证列

时间:2011-11-29 10:38:49

标签: ruby-on-rails ruby csv

我有代码检查CSV文件是否正确。我想编写惯用的代码来检查列是否正确。如果我们有第一行检查列,我不想写块检查。

CSV.foreach(@csv) { |person|
  first_name, last_name, person_id, email, title, phone, mobile, department, address, city = person[0..9]
  zip_code, state, country, manager_id =person[10..13]
  @managers << manager_id
  @persons << person_id

  validate = false unless validate_email(email)
  validate = false unless validate_first_name(first_name)
  validate = false unless validate_last_name(last_name)
  validate = false unless validate_person_id(person_id)
}

2 个答案:

答案 0 :(得分:1)

CSV是否有标题或是否可以添加标题?如果是,您可以执行CSV.foreach(@csv, :headers => true)并获取类似person['first_name']的列值。然后最后的检查变为

validate = false unless validate_email(person['email'])

那就是说,似乎你最后的整个验证都可以写成

validate_email(person['email']) && validate_first_name(person['first_name']) etc.

答案 1 :(得分:0)

+1迈克尔对:headers => true

的建议

但是如果你想验证你的例子中的所有命名字段并且是为了DRY(尽管如此,可能有点过于聪明的可维护性),你可以使用Enumerable#inject

CSV.foreach(@cvs, :headers => true) { |person|
  @managers << person[:manager_id]
  @persons << person[:person_id]

  # Array of columns to be validated
  validate_cols = [:first_name, :last_name, :person_id, :email, :title, :phone,
           :mobile, :department, :address, :city, :zip_code, :state,
           :country, :manager_id]

  valid = validate_cols.inject(true){|valid_sum, col|
    valid_sum && send("validate_#{col}", person[col])
  }
}

这假设您为validate_*数组中命名的每个列都有validate_cols个方法。