如何从多个条件中找到与第一个条件匹配的值

时间:2016-05-15 05:17:08

标签: ruby

例如,有一个这样的数组:

a = [1,2,3]

我想找到2的值,但如果不存在,请找3,依此类推5

result = a.find{|i| i == 2} || a.find{|i| i == 3} || a.find{|i| i == 5}

当然真正的价值观更复杂,我能写一下这个功能更简洁吗?

2 个答案:

答案 0 :(得分:1)

我建议使用封装每个条件的单独验证器。它将帮助您解耦业务逻辑。

考虑这一点 - 而不是整数数组,你有Car类实例

class Car
    attr_accessor :producer, :colour, :max_speed

    def initialize(producer, colour, max_speed)
        @producer = producer
        @colour = colour
        @max_speed = max_speed
    end
end

现在你想要通过max_speed,颜色选择汽车,最后选择生产商

cars = [
    Car.new(:ford, :black, 200),
    Car.new(:fiat, :yellow, 170),
    Car.new(:renault, :green, 200),
]

而不是将所有条件放在一个地方,使用单独的验证器

class ColourValidator
    def initialize(colour)
        @colour = colour
    end

    def matching?(car)
        car.colour == @colour
    end
end

class MaxSpeedValidator
    def initialize(max_speed)
        @max_speed = max_speed
    end

    def matching?(car)
        car.max_speed == @max_speed
    end
end

class ProducerValidator
    def initialize(producer)
        @producer = producer
    end

    def matching?(car)
        car.producer == @producer
    end
end
当然,vaidators可能要复杂得多 - 这只是一个想法

并且在一个地方没有创建验证器

validators = [
    ProducerValidator.new(:renault)
]

以及稍后在您的代码中,您可以编写

cars.find { |car| validators.any? { |v| v.matching?(car) } }

好处就是在这里你不必检查具体的业务逻辑,而只是检查任何验证器匹配的返回元素的机制。此外,当新的验证器出现时 - 您只需测试其逻辑而不参考其余的

答案 1 :(得分:0)

您可以使用Array#&

([2,3,5] & [1,2,3]).first #=> 2
([0,3,5] & [1,2,3]).first #=> 3
([0,4,5] & [1,2,3]).first #=> nil

来自doc:“顺序从原始数组中保留。”

@argus'建议(在评论中)不应该被忽视。