Обновление JavaScript Fighting Monsters — бизнес-логика как упражнения

JavaScript

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 есть, но нет в arryB, то добавьте boj со значением ключа a в arryB, а значения других атрибутов могут быть равны '0' следующим образом: {key:'a',num1:'0 ' ,число2:'0',число3:'0',всего':0'}

2. Если в arryA есть a, а в arryB есть obj со значением ключа a, то arryB не меняется, а остальные атрибуты и значения атрибутов в obj остаются неизменными;

3. Если a удаляется в массиве A, то весь объект obj, значением ключа которого является a в массиве B, удаляется.

//准备临时数组
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(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;
}

7. Ответьте на четный логарифм

Это в основном то же самое, что и приведенный выше код, но условие оценки немного отличается, просто вставьте его напрямую, каждый может его увидеть.

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

8. Преобразование метода именования

Например, метод именования верблюжьего регистра изменен на метод именования '-'.

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

9. форматирование символов

Это наиболее распространенные требования к отображению с точки зрения количества, например возврата 10000 на заднем плане. Передний конец должен отображаться как 10000 или другие форматы и т. Д.!

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

10. Объекты объединяются, и записываются аномальные данные

Это требование может быть немного запутанным для всех. Следующий пример анализа
Например, есть два места, где записывается моя информация

let info1={
        name:"守候",
        sex:"男",
        age:24,
        job:"web前端"
    },info2={
        name:"守候!",
        country:"china",
        interest:"basketball",
        phone:"12345678910",
        job:"web前端"
    }

Теперь, чтобы консолидировать мою информацию и записать, что может быть аномальным. Например, указанный выше атрибут имени существует в двух объектах, и значения этих двух объектов различны, поэтому неизвестно, является ли правильным атрибут имени в информации 1 или атрибут имени в информации 2. Поэтому необходимо записать атрибут имени, чтобы в дальнейшем было удобно проверять атрибут имени.

Как показано ниже

Далее шаг за шагом, вне зависимости от 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]));  
     

11. Теги фильтра

Как показано ниже, визуализируйте эту метку ниже

Каждый может сначала подумать, что это совсем не сложно
это массив объектов: например

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)    

С этими данными рендеринг на страницу прост!

12. Импорт содержимого 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. Пока этот массив импортирован, его можно использовать в обычном режиме!

13. Случайные циклы

В то время задача заключалась в том, чтобы фактически отображать информацию о покупателе, что немного напоминало случайный цикл музыкальных проигрывателей.

Есть два требования:
1. В списке подсказок информация подсказки отображается случайным образом каждые 500 мс.
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();

14. Резюме

Ну, о некоторой логике бизнес-требований, которую я собрал, и о том, как ее реализовать, вот и все! Здесь не нужно много логики, но то, что стоит написать и можно использовать в качестве практических вопросов, записано здесь. Реализация моего кода выше может быть немного грубой. Если у вас есть лучший план реализации, предложения приветствуются. Если у вас есть какие-либо потребности, которые можно использовать в качестве практических вопросов, вы можете упомянуть об этом. Пусть у каждого будет несколько практических вопросов, чтобы попробовать и научиться!



------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина