用一个数代表多个状态,二进制运算的一种妙用

318 阅读1分钟

近日学习golang时发现了它对二进制运算的一种妙用。即用一个数来代表多个状态的情况。

下图这种需求在日常开发中很常见

image.png

用户一次可以选择多个选项来提交。

看到这个需求时第一反应就是用一个数组或类数组来存储用户选中的选项。例如:

    // 假设三个选项的id分别为1,2,3
    // 用户选中2,3
    
    [2,3] // 数组形式
    "2,3" // 或者用字符串逗号分隔的形式

这里分享另一种更节省空间的方案:

为了好理解我们用6个选项 假设6个选项的id分别为1,2,4,8,16,32。即:

 Math.pow(2, 0); // 1
 Math.pow(2, 1); // 2
 Math.pow(2, 2); // 4
 Math.pow(2, 3); // 8
 Math.pow(2, 4); // 16
 Math.pow(2, 5); // 32

上述代码也可以写成:

1 << 0 // 1
1 << 1 // 2
1 << 2 // 4
1 << 3 // 8
1 << 4 // 16
1 << 5 // 32

用户如果选中了id为1,4,16的选项,我们将1,4,16做一次二进制的或运算:

    1 | 4 | 16 // 结果为21

得到的结果21,即可代表用户所选的三个选项。

那么怎么用21返推出1,4,16呢?

    
[1, 2, 4, 8, 16, 32].filter((id)=>{
    return (21 & id) === id
})
// 结果为[1,4,16]