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

发布于 2024-10-12 14:36:43 字数 665 浏览 2 评论 0原文

在 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

Is there a better way of handling this in Ruby, while continuing to use the symbols?

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

The obvious way would be swapping out the symbols for number constants, but that's not an option.

pos = 3

if pos >= 1
  puts 'a'
end

if pos >= 2
  puts 'b'
end

if pos >= 3
  puts 'c'
end

Thanks.

EDIT
I just figured out that Ruby orders symbols in alpha/num order. This works perfectly.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

身边 2024-10-19 14:36:43

不确定这是否是最好的方法……

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

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

Not sure if this is the best way......

I would make use of the include? method from array:

puts 'a' if [:pos1, :pos2, :pos3].include? pos
puts 'b' if [:pos1, :pos2].include? pos
puts 'c' if [:pos1].include? pos
唱一曲作罢 2024-10-19 14:36:43

只需使用 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 }

Just use the case statement

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 }
旧城空念 2024-10-19 14:36:43

有很多不同的方法来获取输出。你是哪一个
想要取决于您对 if 语句的具体反对意见。
我添加了一些额外的格式以使输出更容易
阅读。

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

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 方法的问题是什么,很难说什么是最好的;你的第二个例子表明你真正想要的是一种将符号变成序数的方法。

There are lots of different ways to get your output. Which one you
want depends on your specific objections to your if statements.
I've added a bunch of extra formatting to make the output easier
to read.

If you don't like the logical ORs and how they separate the results
from the output, you can use a lookup table:

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}" }
}

Or, if you want all the "work" in the lookup table:

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
}

If your problem is that symbols aren't ordinals, then you can
ordinalize them by converting them to strings:

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
}

Or you could monkey patch a comparison operator into the Symbol
class (not recommended):

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
}

Or you could use a lookup table to supply your ordinal values:

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
}

Those are the obvious ones off the top of my head. It is hard to say what would be best without more specifics on what your problem with your if approach is; your second example indicates that what you really want is a way to make symbols into ordinals.

野侃 2024-10-19 14:36:43

更一般地,您可以使用这个:

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

More generically, you can use this:

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

Or this, for your specific example:

puts 'a'
puts 'b' if pos != :pos3
puts 'c' if pos == :pos1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文