Ruby最佳实践:使用一个运算符来处理if not empty each do else。

24

1.我无法找到一种优雅的方法来编写这段代码:

if array.empty?
  # process empty array
else
  array.each do |el|
    # process el
  end
end

我希望只用一个循环,不重复写array。我看过这个,但没有足够好的解决方案。


2. 我在一个 HAML 模板中,同样的问题。

- if array.empty?
  %p No result
- else
  %ul
  - array.each do |el|
    %li el

1
事实上,您在HAML模板中的情况是关键信息,这使得它不仅仅是一道Ruby问题。在普通的Ruby中,只需循环和处理即可。但由于您处于视图层,您正在生成由数据结构指定的展示数据。我相信您可以使用一些视图方法来简化它。但同时我会丢掉“else”,并创建两个不同的上下文。但请理解,这种区别超出了Ruby范畴。 - danneu
在处理空数组部分,你会做什么? - Shoe
我确实理解HAML在这里是关键,但如果Ruby有适当的运算符,那么就会更容易了,对吧?不过我不确定我理解你的意思。你是如何创建两个不同的上下文的? - Augustin Riedinger
7个回答

37

怎么样?

array.each do |x|
  #...
  puts "x",x
end.empty? and begin
  puts "empty!"
end

我想使用array.each_slice来实现这个功能,但它不起作用。你知道有没有类似的方法吗?谢谢。 - Luis Crespo
3
哦,我的天啊,这就是我喜欢 Ruby 的原因! - David Routen
有没有办法扩展这个功能,同时单独处理.nil?情况? - sschuberth
该死,我已经使用 Ruby 近 15 年了,这是我第一次看到这个。虽然在代码中有点棘手,但真的很干净。谢谢。我会试用一段时间,看看它是否能够很好地处理空的 ArrayActiveRecord::Relation,并成为我们新的标准方式。 - Joshua Pinter

6
我见过在HAML中实现这个的最简洁方式(而不是普通的Ruby)大致如下:

最干净的方法我在HAML中看到的(而不是普通的Ruby)是这样的:

- array.each do |item|
    %li
        = item.name
- if array.empty?
    %li.empty
        Nothing here.

正如其他答案所提到的,不需要else子句,因为它已经包含在其他逻辑中了。
即使您可以在一行中完成每个else,也无法实现您尝试实现的标记(如果array.empty?则<p>,如果array.present?则<ul>)。此外,您在问题中显示的HAML是讲述代码背后故事的最佳方式,这意味着对于其他开发人员来说更易读和可维护,因此我不知道为什么您要重构成更加晦涩的内容。

2
如果array为空,则不会迭代,因此each块不需要被限制。由于each的返回值是接收器,您可以将each块放在empty?条件中。
if (array.each do |el|
  # process el
end).empty?
  # process empty array
end

3
你觉得这算是“优雅”吗? - Sergey Bolgov
3
这个代码实际上符合我的要求,不重复使用数组并且只有一个缩进级别。但是它在HAML中不能运行... - Augustin Riedinger
这是一种非常糟糕的 Ruby 编码方式。请查看 https://github.com/bbatsov/ruby-style-guide#metaprogramming。 - karlihnos

2

我认为没有更加优雅或易读的方式来编写这段代码。任何将迭代和条件结合的方法都会导致黑盒代码,也就是说:条件很可能会被隐藏在一个Array扩展中。


1
假定“处理空数组”在处理后将其保持为空,那么您可以省略else部分。
if array.empty?
  # process empty array 
end
array.each do |el|
  # process el
end

或者一行代码:
array.empty? ? process_empty_array : array.each { |el| process_el } 

0

如果数组为空,则我们可以强制将其设置为空数组

if (array || []).each do |x|
  #...
  puts "x",x
end.empty?
  puts "empty!"
end

-1

我看到有些人在问如何处理 nil 的情况。

诀窍是将其转换为字符串。所有 nil 转成字符串都变成空字符串,所有空的情况仍然为空。

nil.to_s.empty?
"".to_s.empty?

两者都将返回true


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