如何删除数组中的空字符串

6

我希望使用delete_if方法从数组中删除空字符串。但是,下面的解决方案仍然会保留许多空字符串。

products = my_text.split(/\t+/)
products.delete_if {|element| element == " " || "" || element.nil?}

还有什么遗漏吗?


3
这段代码的作用是删除一个数组中所有空白或空元素。 - oldergod
5
你需要将其更改为products.reject! { |product| product.nil? || product.strip.empty? },否则你会尝试对nil进行strip操作。 - Momer
不确定我是否理解了你的更改@Momer。同时,我也想删除空值。oldergod的解决方案似乎已经奏效了。 - Adam Bronfin
1
奇怪,它应该会引发一个错误。基本上,oldergod的块在评估s是否为nil之前向s发送了strip。这应该会引发NoMethodError: undefined method 'strip' for nil:NilClass。通过改变顺序,您可以避免这种情况。 - Momer
6个回答

14
您的代码问题由Ed S.解释。
否则,您可以这样做。
products.reject! { |s| s.nil? || s.strip.empty? }

为什么需要先测试nil? 让我们来看几行代码。

nil.strip
# NoMethodError: undefined method `strip' for nil:NilClass
"   ".strip
# => ""

现在,按照不同的顺序,如果对象是字符串,代码会执行什么操作,然后如果对象是nil。
"  ".strip || "  ".nil?
# => ""
nil.strip || nil.nil?
# NoMethodError: undefined method `strip' for nil:NilClass
# Oh you don't want that to happen, do you?

这意味着当对象为nil时,您不希望调用strip.empty?。而且,正如您所知,当您有a || b时,如果a为真(即非nilfalse),则b将永远不会被调用。
您首先测试字符串是否为nil;如果是,则无需检查右侧(因此您将不会收到未定义的方法错误),并且该对象将从产品列表中删除。

1
从 Ruby 2.3 开始,您可以使用安全导航运算符来避免检查 nilproducts.reject! { |s| s&.strip&.empty? } - Ryan Lue

4

2

这是错误的:

element == " " || "" || element.nil?

应该是这样的

products = products.delete_if {|element| element == " " || element == "" || element.nil?

请注意您在其中使用了||""||。您并没有将element""进行比较,而是测试了""的“真实性”(顺便提一下,""会评估为true,这会破坏您的空字符串检查)。
当然,这假定您对“空字符串”的定义是nil、" """。其他情况怎么办?
"  " 

甚至更多
"         "

?


那确实让我走上了正确的轨道!但现在当我调试它时,那行代码会执行多次,等它完成时会删除整个数组。由于每个字符串至少有一个空格,某种原因布尔值评估为真。 - Adam Bronfin
是的,你在回答中编辑了我的问题,哈哈,果然很有预见性。 - Adam Bronfin
@AdamBronfin:字符串比较不是这样工作的。它不是一个“包含”,而是对值进行比较,仅此而已。请使用@oldergod在评论中提供的建议。 - Ed S.
到目前为止我的经验表明我只受到了“ ”的困扰,而“”|| nil只是出于偏执。但我想我可以包括一个识别某些连续的空白符和空格的正则表达式。 - Adam Bronfin

1

我可能有点晚(你6年前在哪里?),但是这是我的建议,处理nil""" "

arr.compact.map(&:strip).reject(&:empty?)

例如: ["", nil, "toto", " "].compact.map(&:strip).reject(&:empty?) # => ["toto"] 愉快的Covid封锁!

1

String#strip 每个元素都进行处理,然后拒绝空元素:

arr.map!(&:strip).reject!{|s| s.empty?}

1

如果您有一个字符串数组,可以很容易地使用 reject 函数删除空值:

像这样的字符串数组:

array = ["", "ABC", "DEF", ... , "", "ZXY"]

如果使用 reject

array.reject(&:empty?)

会输出一个干净的字符串数组:

=> ["ABC", "DEF", "ZXY"]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接