js多条件判断语句简化 用es6中map简化复杂条件判断(霸霸看了都说好)

这样的的代码过于臃肿,不容易理解,后期维护难度大

const isDel = (op, o) => {
    let fal = false;
    if (op.is_show_lock && op.is_show_sf && op.is_show_bz) {
        if (o.is_lock && o.is_sf && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock && op.is_show_sf) {
        if (o.is_lock && o.is_sf) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock && op.is_show_bz) {
        if (o.is_lock && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_sf && op.is_show_bz) {
        if (o.is_sf && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock) {
        if (o.is_lock) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_sf) {
        if (o.is_sf) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_bz) {
        if (o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    }
    return fal;
};

优化思路

观察问题,总结规律:

op.is_show_xxx o.is_xxx 成对出现
op.is_show_xxx 为 true 的时候才需要判断 o.is_xxx (过滤)
将过滤出来的所有 o.is_xxx &&组合条件,得到计算结果
最终结果正好与计算结果相反
因为 op.is_show_xxx op.is_xxx 数量相当,而且不多。原回答(见下面)通过数组索引的方式来关联他们。然后在一次遍历(reduce 部分)中同时进行过滤(三元运算)和布尔计算(合并 r 值)。因为是 and 运算,所以初始值给 true 。最后将结果取反输出。

原回答这个解法虽然有一定的效率,但不是很容易理解,今天再写个按上面分析分步骤进行的:

function isRemove2(op, o) {
    const result = "lock,sf,bz".split(",")
        .map(suffix => [`is_show_${suffix}`, `is_${suffix}`])
        .map(pair => ({ flag: op[pair[0]], value: o[pair[1]] }))
        // ⇑ 上面三行都只是为了生成 { flag: true, value: true } 这样的关系数据
        // ⇓ 下面这行是按 is_show_xxx 过滤
        .filter(pair => pair.flag)
        // 过滤出来的用 && 组合逻辑
        .reduce((r, pair) => r && pair.value, true);
    return !result;
}

不习惯看这种函数式的处理方式,来个原始一点for…of 循环的

function isRemove3(op, o) {
    const suffixes = "lock,sf,bz".split(",");
    let result = true;
    for (const suffix of suffixes) {
        if (op[`is_show_${suffix}`]) {
            result &&= o[`is_${suffix}`];
        }
    }
    return !result;
}

这一段中的遍历部分(初始化 result for )直接翻译成 reduce 形式就是:

function isRemove4(op, o) {
    const suffixes = "lock,sf,bz".split(",");

    let result = suffixes.reduce(
        (r, suffix) => {
            if (op[`is_show_${suffix}`]) {
                return r && o[`is_${suffix}`];
            } else {
                return r;
            }
        },
        true    // 初始化,相当于 let result = true
    );
    return !result;
}

中间的 if…else…看起来不清爽,处理一下(VS 的重构很方便)
请添加图片描述

function isRemove4(op, o) {
    const suffixes = "lock,sf,bz".split(",");

    let result = suffixes.reduce(
        (r, suffix) => op[`is_show_${suffix}`] ? r && o[`is_${suffix}`] : r,
        true    // 初始化,相当于 let result = true
    );
    return !result;
}

问题中的 isDel 保留,方便做单元测试对比,定义了一个 isRemove

function isRemove(op, o) {
    const flags = [op.is_show_lock, op.is_show_sf, op.is_show_bz];
    const values = [o.is_lock, o.is_sf, o.is_bz];
    return !flags.reduce((r, flag, i) => {
        return flag ? r && values[i] : r;
    }, true);
}

测试用例:

// test cases
(() => {
    const cases = Array.from(Array(8), (_, i) => {
        return [!!(i & 0x01), !!(i & 0x02), !!(i & 0x04)];
    });

    let failed = false;
    const allCases = cases.length * cases.length;
    let passed = 0;
    cases.forEach(flags => {
        const op = {};
        ([op.is_show_lock, op.is_show_sf, op.is_show_bz] = flags);
        cases.forEach(values => {
            const o = {};
            ([o.is_lock, o.is_sf, o.is_bz] = values);
            if (isDel(op, o) === isRemove(op, o)) {
                passed++;
            } else {
                failed = true;
                console.log("[Fail]", op, o);
            }
        });
    });

    if (!failed) {
        console.log(`[All passed]: ${passed}/${allCases}`);
    }
})();
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值