表驱动法(更优雅的写if-else、switch-case)

表驱动法(更优雅的写if-else、switch-case)表驱动法 表驱动法就是一种编程模式 scheme 从表里面查找信息而不使用逻辑语句 if 和 case 事实上 凡是能通过逻辑语句来选择的事物 都可以通过查表来选择 对简单的情况而言 使用逻辑语句更为容易和直白 但随着逻辑链的越来越复杂 查表法也就愈发显得更具吸引力 直接访问 一个很简单的例子

大家好,我是讯享网,很高兴认识大家。

表驱动法

直接访问

一个很简单的例子: 今天星期几

const day = new Date().getDay() let day_zh; if(day === 0){ day_zh = '星期日' }else if(day === 1) { day_zh = '星期一' } ... else{ day_zh = '星期六' } // 或者 用 switch case switch(day) { case 0: day_zh = '星期日' break; case 1: day_zh = '星期一' break; ... } 

讯享网

实现同样功能的一种更简单、更容易修改的方法是把这些数据存到一张表里面。

讯享网const week = ['星期日', '星期一',..., '星期六'] const day = new Date().getDay( const day_zh = week[day] 

第二个例子:假设你需要一个可以返回每个月中天数的函数(为简单起见不考虑闰年)
使用if else

function iGetMonthDays(iMonth) { let iDays; if(1 == iMonth) {iDays = 31;} else if(2 == iMonth) {iDays = 28;} else if(3 == iMonth) {iDays = 31;} else if(4 == iMonth) {iDays = 30;} else if(5 == iMonth) {iDays = 31;} else if(6 == iMonth) {iDays = 30;} else if(7 == iMonth) {iDays = 31;} else if(8 == iMonth) {iDays = 31;} else if(9 == iMonth) {iDays = 30;} else if(10 == iMonth) {iDays = 31;} else if(11 == iMonth) {iDays = 30;} else if(12 == iMonth) {iDays = 31;} return iDays; } 

使用表驱动(包括闰年判断)

讯享网const monthDays = [ [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] ] function getMonthDays(month, year) { let isLeapYear = (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0) ? 1 : 0 return monthDays[isLeapYear][(month - 1)]; } console.log(getMonthDays(2, 2000)) 

对象中的应用
形如:

if (key = "Key A") { 处理 Key A 相关的数据。 } else if (key = "Key B") { 处理 Key B 相关的数据。 } 

讯享网if (key = "Key A") { 执行 Key A 相关的行为。 } else if (key = "Key B") { 执行 Key B 相关的行为。 } 

可以改装成:

let table = { A: { data: "数据1", action: "行为1" }, B: { data: "数据2", action: "行为2" } } function handleTable(key) { return table[key] } console.log(handleTable('A').data) 

讯享网let table = { A: { data: "数据1", action () { console.log('action 1') } }, B: { data: "数据2", action () { console.log('action 2') } } } function handleTable(key) { return table[key] } handleTable('A').action() 

回顾一下我以前写的代码,好多复杂的代码都通过这种方式简化了不少,比如:


讯享网

let vm = this let adTable = { bdkq () { window.clLib.localStorageOperating.updateData('default_hospital_code', '') vm.$router.push('/hospital') }, etyy () { vm.goSp(10012) }, szn () { vm.goCh('szn') } } adTable[data.key] ? adTable[data.key]() : location.href = data.ad_url 

以前是怎么写的呢? 看看就知道了,特别复杂!

讯享网switch (data.key) { case 'bdkq': window.clLib.localStorageOperating.updateData('default_hospital_code', '') this.$router.push('/hospital') break case 'etyy': this.goSp(10012) break case 'szn': this.goCh('szn') break default: location.href = data.ad_url break } 

阶梯访问
这种方法不像索引访问那么直接,但比索引访问要节省空间。

典型的例子就是等级评定

考试按分数评优良中差四个等级

简单做法

 let level = '优' if(score <60 ){ level = '差' }else if(score < 80) { level = '中' }else if(score < 90) { level = '良' } 

如果需要添加等级 60-70 之间 是一般,就需要改逻辑,逻辑简单的还好

讯享网 let level = '优' if(score <60 ){ level = '差' }else if(score < 70) { level = '一般' }else if(score < 80) { level = '中' }else if(score < 90) { level = '良' } 

这时用阶梯查询就比较方便,而且扩展性也好

 const levelTable = ['差', '中', '良', '优'] const scoreCeilTable = [60, 80, 90, 100] function getLevel(score) { const len = scoreCeilTable.length for(let i = 0; i < len; i++) { const scoreCeil = scoreCeilTable[i] if(score <= scoreCeil) { return levelTable[i] } } return levelTable[len - 1] } 

就算后面需要添加等级60-70 —> ‘一般’ 也只需要简单添加数据表就可以了,而不需要修改逻辑

讯享网 const levelTable = ['差', '一般', '中', '良', '优'] const scoreCeilTable = [60, 70, 80, 90, 100] 

阶梯访问表需要注意几个问题

  1. 留心端点
  2. 二分查找替代顺序查找:上面例子用了顺序查找,当数据比较大时,查找成本还是比较大的,应该考虑用二分查找替代顺序查找
  3. 考虑用索引访问来取代阶梯技术,阶梯查找比较耗时,如果速度非常重要,可以用索引访问来取代阶梯,用空间换时间,但也要分情况,因为离散空间是不能够完全替代连续空间的

二分查找跳转

小讯
上一篇 2025-03-31 23:40
下一篇 2025-01-07 09:49

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/65999.html