開發項目和出沒社區有一段時間了,會趕上一些比較有印象業務需求。這些業務需求,多是本身開發項目趕上的,多是在社區看到的業務需求,或者其餘狀況接觸到的需求,可是這些業務需求的實現邏輯都值得一寫。由於這些業務邏輯能夠當作練習題同樣,能夠給你們練手。也但願你們從這些需求實現的邏輯裏面能夠能到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)
具體問題是這樣的:bash
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
}];
複製代碼
一、若是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();
複製代碼
好了,關於我收集到的一些業務需求邏輯,以及實現的方式,就說到這裏了!接觸到的也無需求邏輯不少,可是值得寫的,能夠當作練習題的,就記錄到這裏了。我上面代碼實現可能會有點粗糙,你們有更好的實現方案,歡迎建議一下。若是你們有什麼能夠當作練習題的需求,能夠提下。讓你們有多些練習題能夠嘗試下,學習下!
-------------------------華麗的分割線--------------------
想了解更多,關注關注個人微信公衆號:守候書閣