我有四个布尔变量v0, v1, v2, v3
,想要得到它们表示的整数,将v
作为二进制数字,将其值false
作为0
和true
为1
,换句话说:
8 * v3 + 4 * v2 + 2 * v1 + v0
将它们转换为此类整数的最佳方法是什么?这可以直接在矢量中完成吗?
答案 0 :(得分:4)
只是迭代。无需动力操作。
[false, true, false, true] .inject(0){|n, b| n * 2 + (b ? 1 : 0)} # => 5
[false, false, false, false].inject(0){|n, b| n * 2 + (b ? 1 : 0)} # => 0
[false, false, false, true] .inject(0){|n, b| n * 2 + (b ? 1 : 0)} # => 1
[true, false, false, true] .inject(0){|n, b| n * 2 + (b ? 1 : 0)} # => 9
答案 1 :(得分:3)
只需创建一个自定义方法:
def bool_to_int(bool)
bool ? 1 : 0
end
8*bool_to_int(v3) + 4*bool_to_int(v2) + 2*bool_to_int(v1) + bool_to_int(v0)
您当然可以使用数组并将函数调用应用于列表中的所有值。
ary = [false, true, true, false]
exp = 0
ary.inject(0) do |total, value|
total += bool_to_int(value) * (2**exp)
exp += 1
total
end
这更简洁。数组中的第一项是指数,第二项是总和。
ary = [false, true, true, false]
ary.inject([0,0]) do |(exp, total), value|
[exp + 1, total + bool_to_int(value) * (2**exp)]
end
正如评论中所指出的,您也可以使用<<
ary = [false, true, true, false]
ary.inject([0,0]) do |(exp, total), value|
[exp + 1, total + (bool_to_int(value) << exp)]
end
答案 2 :(得分:1)
在此特定示例中,您可以将to_i
方法直接添加到true
和false
:
def false.to_i
0
end
def true.to_i
1
end
def int_from_boolean_array(array)
sum = 0
array.each_with_index do |el, index|
sum += el.to_i * (2**index)
end
sum
end
int_from_boolean_array([false, true, false, true])
它有效,因为true
(false
相同)只是ruby中的简单对象,因此您可以扩展它。你也可以用稍微不同的方式写出相同的内容:
class TrueClass
def to_i
1
end
end
class FalseClass
def to_i
0
end
end
第一种方法有效,因为系统中始终只有TrueClass
和FalseClass
的一个实例。
答案 3 :(得分:1)
您可以修补TrueClass
和FalseClass
以回复*
和+
方法。这是一个主要基于本主题讨论的工作解决方案 - In Ruby, how does coerce() actually work?
# Changes to `TrueClass` and `FalseClass`
class TrueClass
def *(i)
i * 1
end
def +(i)
i + 1
end
def coerce(something)
[self, something]
end
end
class FalseClass
def *(i)
i * 0
end
def +(i)
i + 0
end
def coerce(something)
[self,something]
end
end
# Sample Runs
v3,v2,v1,v0 = true,false,true,true
p v3*8 + v2*4 + v1*2 + v0
#=> 11
p 8*v3 + 4*v2 + 2*v1 + v0
#=> 11
p 8*true + 4*false + 2*false + true
#=> 9