专栏名称: 守候i
web前端开发
目录
相关文章推荐
51好读  ›  专栏  ›  守候i

JavaScript 打怪升级 —— 把业务逻辑当练习题做

守候i  · 掘金  · 前端  · 2017-12-20 00:47

正文

1.前言

开发项目和出没社区有一段时间了,会遇上一些比较有印象业务需求。这些业务需求,可能是自己开发项目遇上的,可能是在社区看到的业务需求,或者其他情况接触到的需求,但是这些业务需求的实现逻辑都值得一写。因为这些业务逻辑可以当做练习题一样,可以给大家练手。也希望大家从这些需求实现的逻辑里面可以能到javascript的相关知识,当然如果大家觉得代码需要怎样优化,或者有什么建议,更好的实现方案,觉得我哪里写错了,或者有觉得可以分享的需求,可以在评论提下!

2.月份坐标轴

这个需求是,看下图就懂了

实现方式其实很简单,我在代码打上注释,大家就懂了!

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();

可能大家看着会懵,直接看下面的循环图就懂了

3.数值区间

如下图,就是几个数值区间,而且会有一个最小值和最大值

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;
            }
        }
    }
}

测试用例

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}];  

运行结果

4.数组对比

这个基于我回答过的一个问题,现在化用,改写一下

JavaScript如何对比两个数组?数组B根据数组A来做出增删? (不用jquery,原生js)
具体问题是这样的:

arryA

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
}];

1、如果arryA中有a,arryB中没有,那么在arryB中增加一个key值为a的boj,且其他属性值可均为'0';如下: {key:'a',num1:'0',num2:'0',num3:'0',tot':0'}

2、如果arryA中有a,arryB中也有key值为a的obj,那么arryB则不改变,并且该obj里的其他属性和属性值均不变;

3、如果在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);

5.学院获奖

统计学生申请优秀毕业生,并且符合条件的(成绩优秀,拿过奖学金,获得过三好学生)。前提是要申请

大概的流程图就是像下面这样!

我在代码上写上注释,相信不难理解了

//学生列表
//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);

6.数组连续的最大长度

这个也是出于我回答过的问题:如下

//假如有一个数组,下面这个数组最大的连续长度就是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






请到「今天看啥」查看全文