2014-09-22 52 views
1

编辑阵列的单元我写了下面的:如何从功能红宝石

def clean(row) 
    row.each.with_index do |cell, index| 
    next if cell.nil? 

    # Replace all spaces and non-breakable spaces by regular spaces 
    cell.gsub!(/\A\p{Space}*/, ' ') 

    # Remove leading and trailing spaces 
    cell.strip! 

    # Homogenize empty values by setting everything to `nil` 
    row[index] = nil if cell.empty? 
    end 
end 

块的最后一行是想要什么,我请你注意。我想知道这是否是真正改变原始行相关单元格值的唯一方法?如果没有,是否有更聪明的方法来做到这一点?


编辑

下面是使用@ascar答案的最终版本:

def clean(row) 
row.map! do |cell| 
    if cell.nil? || cell.empty? 
    nil 
    else 
    cell.gsub!(/\A\p{Space}*/, ' ') 
    cell.strip! 
    cell.empty? ? nil : cell 
    end 
end 
end 
+0

我没有看到任何错误的代码。但是,如果您使用的是ActiveSupport,则可以使用[String#blank?](http://guides.rubyonrails.org/active_support_core_extensions.html#blank-questionmark-and-present-questionmark),而不是自己转换并检查空白处,它可以清理代码。 – 2014-09-22 16:31:02

+0

你能否提供你的'行'对象的样本? – 2014-09-22 16:39:47

+1

@Adrien Giboire链接!方法是危险的。例如GSUB!如果没有被替换,将返回nil而不是原始字符串。 – dfherr 2014-09-24 11:16:31

回答

1

Array#map!应该做你想要什么

def clean(row) 
row.map! do |cell| 
    if cell.nil? || cell.empty? 
    nil 
    else 
    cell.gsub(/\A\p{Space}*/, ' ').strip 
    end 
end 
end 

,或者如果您使用Array#map想要返回新的数组和不要在原地编辑。

+0

经过测试,似乎并不像最初的'row'完全改变了。即使使用'map!',ruby也不会在任何东西之前创建'row'的副本? – 2014-09-23 16:57:42

+0

ruby​​在将它传递给方法时创建引用的副本,但仍指向同一个对象。所以'map!'仍然会改变原始行对象(数组)的内容。我在irb中试过,传入的行对象的内容根据你的方法改变了。你能提供错误或更详细的信息吗?如果你有任何直接引用的单元格,它们将保持不变,这种方法因为gsub/strip会返回它们的新副本。如果还要编辑单元格,则需要您的代码更清洁。 – dfherr 2014-09-23 17:29:02

+0

你绝对是对的。我只是感到困惑,因为你的方法和我的做法不一样。无论如何,谢谢,'map!'完成这项工作:)我将用最终解决方案编辑我的问题。 – 2014-09-24 10:48:20