我想检查一个值是否对应于一组标志(来自枚举或对象)。
现在,我已经在javascript中提出了以下功能(赞美代码段:3):
function hasFlags(flags, value) {
let s = flags.reduce((sum, v) => sum += v, 0);
return (s & value) === s
}
FLAGS = {
STEP_0: 1 << 0,
STEP_1: 1 << 1,
STEP_2: 1 << 2,
STEP_3: 1 << 3,
STEP_4: 1 << 4,
STEP_5: 1 << 5,
STEP_6: 1 << 6,
STEP_7: 1 << 7
}
const needed = [
FLAGS.STEP_2,
FLAGS.STEP_3,
FLAGS.STEP_6,
]
console.log(hasFlags(needed, 4)); // false
console.log(hasFlags(needed, 8)); // false
console.log(hasFlags(needed, 64)); // false
console.log(hasFlags(needed, 4 + 8)); // false
console.log(hasFlags(needed, 4 + 64)); // false
console.log(hasFlags(needed, 8 + 64)); // false
console.log(hasFlags(needed, 4 + 8 + 64)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 1)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 2)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 1 + 2)); // true
// etc...
&#13;
在python中,函数看起来像这样:
def hasFlags(flags, value):
s = sum(flags)
return (s & value) == s
print hasFlags((4,8,64), 4) # False
print hasFlags((4,8,64), 4+8+64) # True
# ...
有没有更好的方法(也就是更多惯用...或更多pythonic)来做同样的验证?
编辑:python和javascript中的解决方案都很受欢迎,但我特别想找到一种算法(无论语言是什么),因为我在网上搜索过很多但从未找到任何算法,而在我看来这是一个常见的问题。
答案 0 :(得分:0)
您可以查看Array#every
,如果条件错误则退出。
operator []
const
hasFlags = (flags, value) => flags.every(flag => flag & value),
FLAGS = {
STEP_0: 1 << 0,
STEP_1: 1 << 1,
STEP_2: 1 << 2,
STEP_3: 1 << 3,
STEP_4: 1 << 4,
STEP_5: 1 << 5,
STEP_6: 1 << 6,
STEP_7: 1 << 7
},
needed = [
FLAGS.STEP_2,
FLAGS.STEP_3,
FLAGS.STEP_6,
];
console.log(hasFlags(needed, 4)); // false
console.log(hasFlags(needed, 8)); // false
console.log(hasFlags(needed, 64)); // false
console.log(hasFlags(needed, 4 + 8)); // false
console.log(hasFlags(needed, 4 + 64)); // false
console.log(hasFlags(needed, 8 + 64)); // false
console.log(hasFlags(needed, 4 + 8 + 64)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 1)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 2)); // true
console.log(hasFlags(needed, 4 + 8 + 64 + 1 + 2)); // true
答案 1 :(得分:0)
Python中的一个选项是set
个标志,其中flags是(例如)来自enum
模块的枚举的元素。这也有已经定义的子集运算符的好处,因此您可以执行needed <= flags
。
您的最终代码如下所示:
from enum import Enum
class Flags(enum.Enum):
flag0 = {0}
flag1 = {1}
flag2 = {2}
...
def has_flags(needed, flags):
return needed <= flags
needed = Flags.flag2 |
Flags.flag3 |
Flags.flag6
print(has_flags(needed, Flags.flag2)) #false
print(has_flags(needed, Flags.flag3)) #false
...
答案 2 :(得分:0)
当标志组合表示为位掩码时,您可以使用逐位运算符直接对所有标志进行突变和测试。
STEP_0 = 1 << 0
STEP_1 = 1 << 1
STEP_2 = 1 << 2
STEP_3 = 1 << 3
STEP_4 = 1 << 4
STEP_5 = 1 << 5
STEP_6 = 1 << 6
STEP_7 = 1 << 7
def has_flags(flags_to_check_for, cur_flags):
return (cur_flags & flags_to_check_for) == flags_to_check_for
desired_flags = STEP_2 | STEP_3 | STEP_6
cur_flags = STEP_2
print has_flags(desired_flags, cur_flags) # False
cur_flags |= STEP_3
cur_flags |= STEP_6
print has_flags(desired_flags, cur_flags) # True
# ...