zoukankan      html  css  js  c++  java
  • 使用二进制来表示步骤完成进度

    一、原因

    日常项目中可能会遇到的场景,比如

    1、记录用户完成的多个步骤
    2、用户提交信息后,后台审核驳回的多个原因字段
    ...
    

    这些如果用多个字段表示会非常麻烦,而且不好记,多余

    我们可以使用二进制的形式来包含不同的状态


    二、使用方式

    /**
     * description:根据 二进制转换成的 10 进制,经过对比得到下一个未完成的步骤
     * @param {Number} stepBinaryToTenHex 二进制转换的10进制值
     * @param {Number} maxStep 最大可记录步骤数,默认为 8
     * */
    function calcNextStep(stepBinaryToTenHex, maxStep = 8) {
        // 默认步数为第 1 步
        let power = 1
        for (let step = 1; step <= maxStep; step++) {
            if ((stepBinaryToTenHex & power) === 0) {
                // 若 `与操作` 结果为 0
                // 说明当次步骤还未完成,返回该步骤
                return step
            }
            // 若 `与操作` 结果不为 0,说明是已完成
            // 继续增大 2 的幂次方
            power *= 2
        }
    }
    完成第一步:0000 0001 --> 1     calcNextStep(1)     // 下一个未完成步骤为:2
    完成第二步:0000 0011 --> 3     calcNextStep(3)     // 下一个未完成步骤为:3
    完成第三步:0000 0111 --> 7     calcNextStep(7)     // 下一个未完成步骤为:4
    完成第四步:0000 1111 --> 15    calcNextStep(15)    // 下一个未完成步骤为:5
    完成第五步:0001 1111 --> 31    calcNextStep(31)    // 下一个未完成步骤为:6
    完成第六步:0011 1111 --> 63    calcNextStep(63)    // 下一个未完成步骤为:7
    完成第七步:0111 1111 --> 127   calcNextStep(127)   // 下一个未完成步骤为:8
    完成第八步:1111 1111 --> 255   calcNextStep(255)   // undefined
    
    

    注意:
    stepBinaryToTenHex 才是前端和后端存储的值,并不是直接使用二进制保存


    三、原理

    1. 表示

    用 0000 0000 表示 1 - 8 个步骤

    从右到左,依次表示 第 1 步第 8 步 的完成情况

    二进制位上为 1 的表示该步骤已经完成,为 0 表示未完成

    1:  0000 0001
    2:  0000 0011
    3:  0000 0111
    4:  0000 1111
    5:  0001 1111
    6:  0011 1111
    7:  0111 1111
    8:  1111 1111
    

    假如:我们此时走到第四步

    // step 为 4
    // stepBinary 二进制 为 00001111
    // stepBinaryToTenHex 为 15
    4:  00001111
    

    2. 计算

    那么我们想知道还未开始的 step 是多少?

    可以使用 与操作(&)

    与操作的规则是

    0 & 0 = 0
    0 & 1 = 0
    1 & 1 = 1
    

    下面是 2 的递增次方值,转换成 2 进制 powerBinary 后都只有一个 1

    根据 与操作 的特点,我们可以将 stepBinarypowerBinary 进行 与操作

    得到的结果为 0,则说明该步没有完成

    1:     0000 0001
    2:     0000 0010
    4:     0000 0100
    8:     0000 1000
    16:    0001 0000
    32:    0010 0000
    64:    0100 0000
    128:   1000 0000
    

    3. 例子

    比如 第 4 步相应的的二进制和 powerBinary 依次 与操作

    4:  0000 1111
    2^1: 0000 0001 --> 结果为:  0000 0001
    2^2: 0000 0010 --> 结果为:  0000 0010
    2^3: 0000 0100 --> 结果为:  0000 0100
    2^4: 0000 1000 --> 结果为:  0000 1000
    2^5: 0001 0000 --> 结果为:  0000 0000 此处 `与操作` 结果为 0,说明未完成
    

    由此可以得到结论: 第五步没有完成

    用 javascript 实现如下

    /**
     * description:根据 二进制转换成的 10 进制,经过对比得到下一个未完成的步骤
     * @param {Number} stepBinaryToTenHex 二进制转换的10进制值
     * @param {Number} maxStep 最大可记录步骤数,默认为 8
     * */
    function calcNextStep(stepBinaryToTenHex, maxStep = 8) {
        // 默认步数为第 1 步
        let power = 1
        for (let step = 1; step <= maxStep; step++) {
            if ((stepBinaryToTenHex & power) === 0) {
                // 若 `与操作` 结果为 0
                // 说明当次步骤还未完成,返回该步骤
                return step
            }
            // 若 `与操作` 结果不为 0,说明是已完成
            // 继续增大 2 的幂次方
            power *= 2
        }
    }
    calcNextStep(15) // 5
    
  • 相关阅读:
    10个超实用的PHP代码片段
    MySQL支撑百万级流量高并发的网站部署详解
    程序员总结:帮助你早些明白一些道理
    50个最常用的UNIX / Linux命令(结合实例)
    php.ini 核心配置选项说明
    智能指针的死穴 循环引用
    滥用vector带来的瓶颈
    JS——层的遮罩效果
    【趣】无广告看视频
    【SQLServer】远程访问数据库进行配置
  • 原文地址:https://www.cnblogs.com/linjunfu/p/13065168.html
Copyright © 2011-2022 走看看