Ruby best practice : if not empty each do else in

2020-06-30 12:09发布

1.I can't find an elegant way to write this code:

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

I'd like to have one loop, without writing array twice. I read this, but there is no solution good enough.


2. I am actually in an HAML template. Same question.

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

7条回答
时光不老,我们不散
2楼-- · 2020-06-30 12:12

I think there is no much more elegant or readable way to write this. Any way to somehow combine an iteration with a condition will just result in blackboxed code, meaning: the condition will just most likely be hidden in an Array extension.

查看更多
可以哭但决不认输i
3楼-- · 2020-06-30 12:12

Assuming that "process empty array" leaves it empty after processing, you can leave out the else:

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

or in one line:

array.empty? ? process_empty_array : array.each { |el| process_el } 
查看更多
冷血范
4楼-- · 2020-06-30 12:16

The cleanest way I've seen this done in HAML (not plain Ruby) is something like:

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

As mentioned by other answers, there is no need for the else clause because that's already implied in the other logic.

Even if you could do the each-else in one clean line, you wouldn't be able to achieve the markup you're trying to achieve (<p> if array.empty?, <ul> if array.present?). Besides, the HAML you show in your question is the best way to tell the story behind your code, which means it will be more readable and maintainable to other developers, so I don't know why you would want to refactor into something more cryptic.

查看更多
我只想做你的唯一
5楼-- · 2020-06-30 12:16

An if the array is nil then we can enforce to empty array

if (array || []).each do |x|
  #...
  puts "x",x
end.empty?
  puts "empty!"
end
查看更多
乱世女痞
6楼-- · 2020-06-30 12:19

I saw some people asking how to handle this for nil cases.

The trick is to convert it to string. All nils converted to string becomes a empty string, all empty cases continue being empty.

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

both will return true

查看更多
beautiful°
7楼-- · 2020-06-30 12:25

What about?

array.each do |x|
  #...
  puts "x",x
end.empty? and begin
  puts "empty!"
end
查看更多
登录 后发表回答