嵌套If语句的Ruby方式

时间:2013-11-21 20:59:19

标签: ruby

现在,我觉得将变量设置为一个非常难看的方式取决于它是否返回一个空字符串。以下是有问题的方法(它使用Nokogiri,但这对于这个问题并不重要)。

def get_let(response)
    if response.css('A').empty?
        if response.css('B').empty?
            let = ''
        end
        let = response.css('B')
    else
        let = response.css('A')
    end

    return let
end

6 个答案:

答案 0 :(得分:4)

def get_let(response)
    let = response.css('A')
    let = response.css('B') if let.empty?
    let = '' if let.empty?
end

答案 1 :(得分:3)

这不像@ sethcall的回答那么可读,但是如果你知道一些Ruby习语,它应该是相当可读的:

def get_let(response)
  responses = [response.css('A'), response.css('B')]
  responses.detect { |response| !response.empty? } || ''
end

detect返回块不返回false的第一个结果。这样做的好处是可以避免条件限制,如果这是你想要的东西。如果你想在上面的答案中没有||,你可以这样做:

def get_let(response)
  responses = [response.css('A'), response.css('B')]
  responses.detect(-> { '' }) { |response| !response.empty? }
end

尽管如此,我并未发现第二种解决方案几乎与第一种解决方案一样直观。如果你只能指定一个空字符串作为参数,那就太棒了。但是,detect及其别名find的参数必须为nil或响应call方法的内容,如lambda或proc。实际上没有理由传入nil,因为这是默认值。

如果您确定response.css方法无法返回其中包含nilfalse值的数组,则可以尝试此解决方案:

def get_let(response)
  responses = [response.css('A'), response.css('B')]
  responses.detect(&:any?) || ''
end

请参阅Ruby文档以阅读有关how detect works的更多信息。以下是docs on any?

答案 2 :(得分:2)

删除return并让:

def get_let(response)
    if response.css('A').empty?
        response.css('B').empty? ? '' : response.css('B')
    else
        response.css('A')
    end
end

或者使用集合:

def get_let(response)
    ['A', 'B'].map { |l| response.css(l) }.find { |items| !items.empty? } || ''
end

避免两次计算CSS选择器。

答案 3 :(得分:0)

我会做这样的事情,非常明确地发生了什么,没有分支逻辑来跟踪它的推理。

def get_let(response)
    return '' if response.css('A').empty? && response.css('B').empty?
    return response.css('B') if response.css('A').empty?
    return response.css('A') if response.css('B').empty?
end

答案 4 :(得分:0)

你不需要let - 让它返回if / else块的结果......我更喜欢保持这样,因为它比三元组更容易阅读......

def get_let(response)
  if response.css('A').empty?
    if response.css('B').empty?
      ''
    else
      response.css('B')
    end
  else
    response.css('A')
  end
end

答案 5 :(得分:0)

def get_let(response)
  case
    when !response.css('A').empty?
      response.css('A')
    when response.css('A').empty? && !response.css('B').empty?
      response.css('B')
    else
     ''
  end
end