【问题标题】:Ruby String to Date parsing error: can't convert Date into StringRuby字符串到日期解析错误:无法将日期转换为字符串
【发布时间】:2017-08-28 17:02:53
【问题描述】:

这个错误似乎不应该发生。

我有一个二维数组:

a = [["Person", "20 Mar 2017", "20 Mar 2017", "Party"], 
["Person2", "02/27/2017", "02/28/2017", "BDay"]]

我正在循环使用此代码将字符串日期解析为 Date 对象的数组:

a.each do |i| 
 i.each do
  i[1] = Date.parse(i[1]) && i[2] = Date.parse(i[2]) rescue i[1] = Date.strptime(i[1], "%m/%d/%Y") && i[2] = Date.strptime(i[2], "%m/%d/%Y")
 end
end

执行代码时出现类型错误:can't convert Date into String 但是我没有将任何 Date 对象转换为字符串,并且当我在循环之外单独解析字符串时它可以工作,但在循环中它会引发此错误。

我不明白为什么会这样。

【问题讨论】:

  • 您希望通过i.each do 实现什么目标?
  • i.each do 以我的理解为内部数组中的每个索引执行它下面的代码。
  • 我现在看到i.each do 是多余的

标签: arrays ruby string loops date


【解决方案1】:

这段代码有两个问题:

  1. i.each do 没有意义;
  2. 运算符优先级很重要-

也就是说:

a.each do |i| 
  (i[1] = Date.parse(i[1]) && i[2] = Date.parse(i[2])) \
    rescue (i[1] = Date.strptime(i[1], "%m/%d/%Y") && i[2] = Date.strptime(i[2], "%m/%d/%Y"))
end 

这样做的更红宝石的方式:

result = a.map do |i|
  i.map do |e|
    Date.parse(e) rescue Date.strptime(e, "%m/%d/%Y") rescue e
  end
end

正如@Stefan 在 cmets 中所说,明确地改变所需的索引可能会更好:

result = a.map do |i|
  i.map.with_index do |e, idx|
    case idx
    when 1..2
      Date.parse(e) rescue Date.strptime(e, "%m/%d/%Y")
    else e
    end
  end
end

【讨论】:

  • 好我改一下i.each do第二行后面的反斜杠是做什么的?
  • 它告诉 ruby​​ 解析器该行将在下一行继续。我已经用更具可读性的 sn-p 更新了答案,它不会就地改变对象。
  • 您能否向我解释为什么除了i.each do 之外,我的代码会抛出错误,以便我了解发生了什么?看起来您的代码在您的第一个示例中是相同的,除了 i.each do 和反斜杠后跟一个新行。
  • 我的代码在条件周围有括号,更正了运算符的优先级。没有括号时,它被视为(a) && (b rescue c),仅拯救后一种情况,而在第一个条件中引发异常并且仍然​​没有被拯救。
  • 您应该将日期解析限制为索引 1 和 2。
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
相关资源
最近更新 更多