开发项目和出没社区有一段时间了,会赶上一些比较有印象业务需求。这些业务需求,多是本身开发项目赶上的,多是在社区看到的业务需求,或者其余状况接触到的需求,可是这些业务需求的实现逻辑都值得一写。由于这些业务逻辑能够当作练习题同样,能够给你们练手。也但愿你们从这些需求实现的逻辑里面能够能到javascript的相关知识,固然若是你们以为代码须要怎样优化,或者有什么建议,更好的实现方案,以为我哪里写错了,或者有以为能够分享的需求,能够在评论提下!javascript
这个需求是,看下图就懂了前端
实现方式其实很简单,我在代码打上注释,你们就懂了!java
var _date=[],dateData=["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]; //准备一个月份反转的数组 var dateDataRet=Object.assign([],dateData).reverse(); //获取当前年份 var yearText=new Date().getFullYear(); //获取当前月份 调试的时候,你们能够经过调整now调试 3月-now=2,12月now=11... var now=new Date().getMonth(); for(let i=0;i<6;i++){ if(now-i<0){ //若是now-i<0,从dateDataRet里面拿数据,下标=|now-i|-1。 _date.push(yearText-1+'年'+dateDataRet[Math.abs(now-i)-1]); } else{ //从dateData里面拿数据,下标=now-i _date.push(yearText+'年'+dateData[now-i]); } } _date.reverse();
可能你们看着会懵,直接看下面的循环图就懂了node
以下图,就是几个数值区间,并且会有一个最小值和最大值jquery
var _min=5,_max=50; function checkArr(arr,min,max){ //排序 arr.sort(function(n1,n2){return n1.min-n2.min}) //遍历 for(var i=0;i<arr.length;i++){ //区间的最小值不能大于等于区间最大值 if(arr[i].min>=arr[i].max){ console.log('区间的最小值不能大于等于区间最大值'); return; } //区间的最小值不能小于默认最小值 if(arr[i].min<min){ console.log('区间的最小值不能小于默认最小值'); return; } //区间的最大值不能大于默认最大值 if(arr[i].max>max){ console.log('区间的最大值不能大于默认最大值'); return; } //元素对比,从第二个元素开始 if(i>0){ //minInclude,maxInclude,为false就是不包含,为true就是包含 //{min:10,max:20,minInclude:false,maxInclude:false} //等同于(10,20) //{min:20,max:30,minInclude:true,maxInclude:false} //等同于[20,30); //若是前一个的最大值和当前的最小值都是包含状况,那么当前区间的最小值必定要比前一个区间的最大值大1 if(arr[i].minInclude&&arr[i-1].maxInclude&&arr[i].min-arr[i-1].max!==1){ console.log('取值范围错误-当前区间的最小值和前一个区间的最大值都是包含状况,当前区间的最小值必定要比前一个区间的最大值大1'); return; } //若是前一个的最大值和当前的最小值。一个是包含,一个是不包含,那么当前区间的的最小值必定要等于上一个区间的最大值 else if(arr[i].minInclude!==arr[i-1].maxInclude&&arr[i].min!==arr[i-1].max){ console.log('取值范围错误-当前区间的最小值和前一个区间的最大值其中一个是包含,一个是不包含状况,当前区间的最小值必定要等于前一个区间的最大值'); return; } //若是前一个的最大值和当前的最小值都是不包含,确定不知足 else if((!arr[i].minInclude)&&(!arr[i-1].maxInclude)){ console.log('取值范围错误-前一个的最大值和当前的最小值都是不包含状况,不知足收尾相连'); return; } } } }
测试用例web
var arr1=[{min:10,max:20,minInclude:false,maxInclude:true},{min:21,max:30,minInclude:true,maxInclude:true}], arr2=[{min:10,max:20,minInclude:false,maxInclude:true},{min:20,max:30,minInclude:true,maxInclude:false}], arr3=[{min:10,max:20,minInclude:false,maxInclude:true},{min:20,max:30,minInclude:false,maxInclude:false}], arr4=[{min:10,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:true,maxInclude:false}], arr5=[{min:10,max:20,minInclude:false,maxInclude:false},{min:21,max:30,minInclude:true,maxInclude:false}], arr6=[{min:10,max:20,minInclude:false,maxInclude:false},{min:15,max:30,minInclude:false,maxInclude:false}], arr7=[{min:10,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}], arr8=[{min:1,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}], arr9=[{min:20,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}], arr10=[{min:20,max:30,minInclude:false,maxInclude:false},{min:20,max:70,minInclude:false,maxInclude:false}];
运行结果npm
这个基于我回答过的一个问题,如今化用,改写一下数组
JavaScript如何对比两个数组?数组B根据数组A来作出增删? (不用jquery,原生js)
具体问题是这样的:微信
arryAapp
var arrayA = ['a','b','c'];
arryB
var arrayB = [{ key:'a', num1:'1', num2:'2', num3:'3', tot:'6' },{ key:'b', num1:'11', num2:'22', num3:'33', tot:'66' },{ key: 'c', num1: '111', num2: '222', num3: '333', tot:666 }];
一、若是arryA中有a,arryB中没有,那么在arryB中增长一个key值为a的boj,且其余属性值可均为'0';以下: {key:'a',num1:'0',num2:'0',num3:'0',tot':0'}
二、若是arryA中有a,arryB中也有key值为a的obj,那么arryB则不改变,而且该obj里的其余属性和属性值均不变;
三、若是在arryA中删除了a,那么arryB中key值为a的obj整个删掉。
//准备临时数组 function compareArr(arr1,arr2){ var result=[],arr; //遍历 for(var i=0;i<arr1.length;i++){ //根据arr1[i]的值,查找arrayB,若是arr2中的有知足条件(arrayB中的对象,有key值等于arrayA[i])的项,就会返回知足条件的项,不然返回underfind; arr=arr2.find(function(val){return val.key===arr1[i]}); //若是arr不是undefind,就会添加arr,不然添加{key:arrayA[i],num1:'0',num2:'0',num3:'0',tot:'0'}。 arr?result.push(arr):result.push({key:arrayA[i],num1:'0',num2:'0',num3:'0',tot:'0'}); } }
测试
var arrayA = ['b','c']; var arrayB = [{ key:'a', num1:'1', num2:'2', num3:'3', tot:'6' },{ key:'b', num1:'11', num2:'22', num3:'33', tot:'66' },{ key: 'c', num1: '111', num2: '222', num3: '333', tot:666 }]; compareArr(arrayA,arrayB);
统计学生申请优秀毕业生,而且符合条件的(成绩优秀,拿过奖学金,得到过三好学生)。前提是要申请
大概的流程图就是像下面这样!
我在代码上写上注释,相信不难理解了
//学生列表 //isApply:是否有申请优秀毕业生 let studentList = [ { name: 'aa', isApply: false, id: 1 }, { name: 'bb', isApply: true, id: 2 }, { name: 'cc', isApply: true, id: 3 } ]; //申请优秀毕业生的学生 isApply:true let _student = studentList.filter(function (item) { return item.isApply; }); //isExcellent:优秀学生的id列表 //isScholarship:得到过奖学金的学生的id列表 //isThreeGood:得到过三好学生的学生的id列表 //accord:集合 let isExcellent = [1, 2, 3, 4, 5], isScholarship = [4, 2, 5, 6, 2, 1, 2], isThreeGood = [2, 1, 4, 52, 36], accord = []; //数组去重函数 function removeRepeatArr(arr) { return arr.filter(function (item, index, self) { return self.indexOf(item) === index; }); } //统计数组中,一个赶上元素的出现次数 function getEleCount(obj, ele) { let num = 0; for (let i = 0, len = obj.length; i < len; i++) { if (ele === obj[i]) { num++; } } return num; } //添加学生记录,把得到成绩优秀的学生的id,得到过奖学金的学生的id,得到过三好学生的id添加进去。 //可是添加以前,要对得到成绩优秀的学生的id,得到过奖学金的学生的id,得到过三好学生的id。这个三个数组进行去重再添加进accord,由于一个学生可能不止一次成绩优秀,不止一次得到过奖学金,不止一次得到过三好学生 //这样就方便下面的判断,只要学生的id在accord里面出现两次及以上就符合条件 accord.push.apply(accord, removeRepeatArr(isExcellent)); accord.push.apply(accord, removeRepeatArr(isScholarship)); accord.push.apply(accord, removeRepeatArr(isThreeGood)); console.log(accord); //符合条件的学生列表 let accordStudent = []; for (let i = 0; i < _student.length; i++) { //只要学生的id在accord里面出现两次及以上 if (getEleCount(accord, _student[i].id) >= 2) { //记录哪些学生符合条件 accordStudent.push(_student[i]); } } console.log(accordStudent);
这个也是出于我回答过的问题:以下
//假若有一个数组,下面这个数组最大的连续长度就是4——————8,9,10,11 var arr=[1,2,4,5,6,8,9,10,11]; //代码实现 function countLen(arr){ //若是参数不是数组或者长度为0,直接返回0 if(arr.constructor!==Array||arr.length===0){return 0;} //首先进入当前连续长度nowLen设初始化为1,最大连续长度maxLen初始化为0 var nowLen=1,maxLen=0; for(var i=1,len=arr.length;i<len;i++){ //当前数组元素是否是比上一个数组大1 if(arr[i]-arr[i-1]===1){ //若是是,当前连续长度nowLen+1 nowLen++; } else{ //不然先判断,当前连续长度是否大于最大连续长度 if(maxLen<nowLen){ //若是是就赋值 maxLen=nowLen } //当前连续长度初始化为1 nowLen=1; } } //循环完再判断一次当前连续长度是否大于最大连续长度(避免最大连续长度是数组最后面几个数组时产生的bug) if(maxLen<nowLen){ maxLen=nowLen } //返回最大连续长度 return maxLen; }
这个和上面的代码基本同样,只是判断条件毫厘之差,直接贴,你们看就好
function countTrue(arr){debugger; //若是参数不是数组或者长度为0,直接返回0 if(arr.constructor!==Array||arr.length===0){return 0;} //首先初始化连续答对长度nowLen为0,最大连续答对长度maxLen为0 var nowLen=0,maxLen=0; for(var i=0,len=arr.length;i<len;i++){ //当前数组元素是否是比上一个数组大1 if(arr[i]){ //若是是,当前连续长度nowLen+1 nowLen++; } else{ //不然先判断,当前连续长度是否大于最大连续长度 if(maxLen<nowLen){ //若是是就赋值 maxLen=nowLen } //当前连续长度初始化为0 nowLen=0; } } //循环完再判断一次当前连续长度是否大于最大连续长度(避免最大连续长度是数组最后面几个数组时产生的bug) if(maxLen<nowLen){ maxLen=nowLen } //返回最大连续长度 return maxLen; }
好比驼峰命名方式转'-'命名方式。
var str = "shouHou"; //$1-第一个括号匹配的内容 //这个实例,$1='H' str = str.replace(/([A-Z])/g,"-$1").toLowerCase();
好比'-'命名方式转驼峰命名方式
var str="shou-hou"; //$0-匹配的结果 $1-第一个括号匹配的内容 //这个实例$0='-h' $1='h' str=str.replace(/-(\w)/g,function($0,$1){ return $1.toUpperCase(); });
这个最多见的就是在金额方面的显示需求上,好比后台返回10000。前端要显示成10,000或者其余格式等!
//str //size-每隔几个字符进行分割 默认3 //delimiter-分割符 默认',' function formatText(str,size,delimiter){ var _str=str.toString(); var _size=size||3,_delimiter=delimiter||','; /* 若是_size是3 "\d{1,3}(?=(\d{3})+$)" */ var regText='\\d{1,'+_size+'}(?=(\\d{'+_size+'})+$)'; /* /\d{1,3}(?=(\d{3})+$)/g 这个正则的意思:匹配连续的三个数字,可是这些三个数字不能是字符串的开头1-3个字符 */ var reg=new RegExp(regText,'g'); /* (-?) 匹配前面的-号 (\d+)匹配中间的数字 ((\.\d+)?)匹配小数点后面的数字 //$0-匹配结果,$1-第一个括号返回的内容----(-?) $2,$3如此类推 */ return _str.replace(/^(-?)(\d+)((\.\d+)?)$/, function ($0, $1, $2, $3) { return $1 + $2.replace(reg, '$&,') + $3; }) }
这个需求,可能你们有点懵。下面实例分析
好比有两个都地方记录了个人信息
let info1={ name:"守候", sex:"男", age:24, job:"web前端" },info2={ name:"守候!", country:"china", interest:"basketball", phone:"12345678910", job:"web前端" }
如今要合并个人信息,而且记录可能有异常的信息。好比上面的name属性,在两个对象都有,并且两个对象的值不同,那么就不知道究竟是info1中的name属性是正确的,仍是info2中的name属性是正确的。因此,就得把name这个属性记录起来,方便之后核对name这个属性。
以下图
下面,一步一步来,先无论3721,直接合并属性
let objAll={}; function assignObj(objArr) { let _obj={}; for(let i=0;i<objArr.length;i++){ _obj=Object.assign(_obj,objArr[i],{}); } return JSON.parse(JSON.stringify(_obj)); } objAll=assignObj([objA,objB]);
而后先准备一个字段,记录哪些异常信息
objAll.warnInfo=[];
最后检查对象,判断哪些信息有异常
function checkObj(_objAll,objList) { //获取全部属性 let _keys=Object.keys(_objAll); for(let i=0;i<objList.length;i++){ for(let j=0;j<_keys.length;j++){ //若是_keys[j]这个属性,在objList[i]和_objAll里面都存在,并且这两个值是不同的,那么就是一场数据,须要记录! if(objList[i][_keys[j]]!==undefined&&_objAll[_keys[j]]!==objList[i][_keys[j]]){ _objAll.isError.push(_keys[j]); } } } return _objAll; } console.log(checkObj(objAll,[objA,objB]));
以下图,在下面渲染这个标签
你们可能第一可能以为压根没难度
就是一个对象数组:好比
var searchTag=[ {label:'产品编码',value:'100072236-8'}, {label:'产品名称',value:'甘油'} ]
可是这样的数据,显然是要通过处理生成的
由于不可能这样发送请求
http://example.com?产品编码=100072236-8
发送过去的参数应该是这样的
http://example.com?proId=100072236-8 var searchParam={proId:'100072236-8',proName:'甘油'}
怎么进行数据的处理呢,其实很简单,代码不打注释,我想都看得懂
var searchTag=[]; var searchText={proId:'产品编码',proName:'产品名称'}; var searchParam={proId:'100072236-8',proName:'甘油'}; Object.keys(searchParam).forEach(function (item) { searchTag.push({ label:searchText[item], key:item, value:searchParam[item] }) }) console.log(searchTag)
有了这些数据,渲染到页面这个就简单了!
就是excel上这样的内容
转成下面的数据
目录以下
下面开始写代码,咱们利用node.js来写
let path = require('path'); //使用ejsexcel读取excel文件 npm install ejsexcel --save let ejsExcel=require('ejsexcel'); let fs=require('fs'); //读取excel let exBuf=fs.readFileSync(__dirname+'/resource/userList.xlsx'); let _data=[]; //获取成功后 ejsExcel.getExcelArr(exBuf).then(exlJson=>{ //获取excel数据 let workBook=exlJson; //获取excel第一张表 sheet1 let workSheets=workBook[0]; //导出js的路径 let newfilepath=path.join(__dirname,"/resource/test.js"); //遍历第一张表的的每一行数据 workSheets.forEach((item,index)=>{ //从第二行开始插入,避免连表头也插入_data里面 if(index>0){ //往_data插入单元格个值,item[0]至关于excel中的姓名,item[1]就是excel中的联系电话 _data.push({ name:item[0], phone:item[1] }) } }); //写入js文件 fs.writeFileSync(newfilepath, 'let _data='+JSON.stringify(_data)+';export {_data}'); }).catch(error=>{ //打印获取失败信息 console.log("读取错误!"); console.log(error); });
而后命令行执行该js
$ node importFile.js
而后就发现多了一个test.js文件
excel的数据就这样导入成js的一个数组了,只要引入这个数组,就能够正常的使用了!
当时接到的业务是实际显示客户的信息,感受有点像音乐播放器的随机循环。
要求有两个:
1.一个提示列表里面,提示的信息每隔500ms随机展现。
2.同一轮循环里面,一个提示信息只能展现一次。
3.列表的提示信息所有展现完了,进行下一轮展现。
这个逻辑没什么,直接在代码打上注释,我想你们就明白了!
var tipList=['提示1','提示2','提示3','提示4','提示5','提示6','提示7','提示8','提示9']; var tipListShow=[]; tipListShow=Object.assign([],tipList); var i=0,timer=null; function play() { //随机显示一个,显示了以后,把这个项从tipListShow中删除掉,防止在同一轮重复出现! console.log(tipListShow.splice(Math.floor(Math.random() * tipListShow.length),1)[0]); //当循环完了以后,tipListShow的长度就会是0,而后就从新赋值,准备进行下一轮的随机循环 if(tipListShow.length===0){ tipListShow=Object.assign([],tipList); i=0; } //若是须要暂停或者中止的,清除这个定时器便可,下次执行就从新这样建立定时器,执行play();! timer=setTimeout(function () { play(); },500); } play();
好了,关于我收集到的一些业务需求逻辑,以及实现的方式,就说到这里了!接触到的业务需求逻辑不少,可是值得写的,能够当作练习题的,就记录到这里了。我上面代码实现可能会有点粗糙,你们有更好的实现方案,欢迎建议一下。若是你们有什么能够当作练习题的需求,能够提下。让你们有多些练习题能够尝试下,学习下!
-------------------------华丽的分割线--------------------
想了解更多,关注关注个人微信公众号:守候书阁