在Ruby中处理这种包容性逻辑的最佳方法是什么?

时间:2011-01-15 16:21:34

标签: ruby logic

有没有更好的方法在Ruby中处理它,同时继续使用符号?

pos = :pos1 # can be :pos2, :pos3, etc.

if pos == :pos1 || pos == :pos2 || pos == :pos3
  puts 'a'
end

if pos == :pos1 || pos == :pos2
  puts 'b'
end

if pos == :pos1
  puts 'c'
end

显而易见的方法是交换数字常量的符号,但这不是一个选项。

pos = 3

if pos >= 1
  puts 'a'
end

if pos >= 2
  puts 'b'
end

if pos >= 3
  puts 'c'
end

感谢。

修改 我只是发现Ruby以alpha / num顺序排序符号。这非常有效。

pos = :pos2 # can be :pos2, :pos3, etc.

if pos >= :pos1
  puts 'a'
end

if pos >= :pos2
  puts 'b'
end

if pos >= :pos3
  puts 'c'
end

4 个答案:

答案 0 :(得分:2)

不确定这是否是最佳方式......

我会使用数组中的include?方法:

puts 'a' if [:pos1, :pos2, :pos3].include? pos
puts 'b' if [:pos1, :pos2].include? pos
puts 'c' if [:pos1].include? pos

答案 1 :(得分:2)

只需使用case声明

即可
pos = :pos1 # can be :pos2, :pos3, etc.

case pos
   when :pos1 then %w[a b c]
   when :pos2 then %w[a b]
   when :pos3 then %w[a]
end.each {|x| puts x }

答案 2 :(得分:1)

有很多不同的方式来获得你的输出。哪一个你 希望取决于您对if陈述的具体反对意见。 我添加了一堆额外的格式以使输出更容易 阅读。

如果您不喜欢逻辑OR以及它们如何分离结果 从输出中,您可以使用查找表:

puts "Lookup table 1:"
lookup_table1 = {
    :pos1 => %w{a b c},
    :pos2 => %w{a b  },
    :pos3 => %w{a    },
}
[:pos1, :pos2, :pos3].each { |which|
    puts "\t#{which}"
    lookup_table1[which].each { |x| puts "\t\t#{x}" }
}

或者,如果您想要查找表中的所有“工作”:

puts "Lookup table 2:"
lookup_table2 = {
    :pos1 => lambda do %w{a b c}.each { |x| puts "\t\t#{x}" } end,
    :pos2 => lambda do %w{a b  }.each { |x| puts "\t\t#{x}" } end,
    :pos3 => lambda do %w{a    }.each { |x| puts "\t\t#{x}" } end,
}
[:pos1, :pos2, :pos3].each { |which|
    puts "\t#{which}"
    lookup_table2[which].call
}

如果您的问题是符号不是序数,那么您可以 通过将它们转换为字符串来对它们进行规范化:

puts "Ordinals by .to_s and <="
[:pos1, :pos2, :pos3].each { |which|
    puts "\t#{which}"
    if which.to_s <= :pos3.to_s
        puts "\t\ta"
    end
    if which.to_s <= :pos2.to_s
        puts "\t\tb"
    end
    if which.to_s <= :pos1.to_s
        puts "\t\tc"
    end
}

或者你可以将比较运算符修补到符号中 课程(不推荐):

puts "Ordinals by Symbol#<="
class Symbol
    def <= (x)
        self.to_s <= x.to_s
    end
end
[:pos1, :pos2, :pos3].each { |which|
    puts "\t#{which}"
    if which <= :pos3
        puts "\t\ta"
    end
    if which <= :pos2
        puts "\t\tb"
    end
    if which <= :pos1
        puts "\t\tc"
    end
}

或者您可以使用查找表来提供您的序数值:

puts "Ordinals through a lookup table:"
ordinal = {
    :pos1 => 1,
    :pos2 => 2,
    :pos3 => 3,
}
[:pos1, :pos2, :pos3].each { |which|
    puts "\t#{which}"
    if ordinal[which] <= 3
        puts "\t\ta"
    end
    if ordinal[which] <= 2
        puts "\t\tb"
    end
    if ordinal[which] <= 1
        puts "\t\tc"
    end
}

这些显而易见的是我的头脑。如果您对if方法的问题没有更详细的说明,很难说什么是最好的;你的第二个例子表明你真正想要的是一种将符号变成序数的方法。

答案 3 :(得分:0)

更一般地说,你可以使用它:

pos = :pos3
arr = [:pos1,:pos2,:pos3]
curr = 'a'

idx = arr.length
while idx > 0
  puts curr if arr.last(idx).include? pos
  curr = curr.next
  idx -= 1
end

或者,对于您的具体示例:

puts 'a'
puts 'b' if pos != :pos3
puts 'c' if pos == :pos1