前幾天記錄了一下表單生成器(Form Builder)之表單數據存儲結構mongodb篇,以後便想着僞造一些數據。爲何要僞造數據呢?說來慚愧,由於拖拉拽設計表單以及表單對應的列表的PC端和移動端該顯示哪些字段而且是否支持搜索打印(即表單的列表配置)等一系列配置都尚未作,還有就是前面只說了表單相關的設計,設計完了以後就是要使用(錄入數據等)對應的這些也尚未作……總之就是如今只有數據結構,可是又想寫一下查詢,因此只能僞造一些數據。又想着這些數據儘可能真實,因此就想寫點代碼來僞造數據。在寫代碼的時候,想隨機生成一個車輛牌照,因此就有了這篇筆記。mongodb
我去,說的太多了,趕忙進入主題。數組
其實結合上篇筆記:獲取一個隨機數,以後生成一個車輛牌照仍是挺簡單的:首先隨機獲取一個省份,而後在數字和字母中隨機獲取6個字符,這樣就拿到了一個車牌照。可是後來想了一下,既然是隨機生成的,就會出現重複的,還有就是新生成的車牌照應該排除目前已經存在車牌照。下面看一下初版,直接上一下代碼:數據結構
var getRangeRandomNumber = function(num1,num2){ num1 = Number.isInteger(num1) ? num1: 0; num2 = Number.isInteger(num2) ? num2: 0; var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2); return Math.round(Math.random() * (maxNum - minNum)) + minNum; }; var getRandomLicensePlate1=function(){ var strProvinceShorter="京"; var strNumberLetter="12345"; var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)]; for(var i=0;i<5;i++){ tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)]; } return tempRetLicensePlate; }; var tempLicensePlateObj={},licensePlateCounter=Math.pow(5,5); for(var i=1;i<=licensePlateCounter;i++){ var temp = getRandomLicensePlate1(); if(tempLicensePlateObj[temp]){ tempLicensePlateObj[temp]++; } else{ tempLicensePlateObj[temp]=1; } } console.log("想要獲取"+licensePlateCounter+"個不一樣的車牌照"); console.log("結果生成了"+Object.getOwnPropertyNames(tempLicensePlateObj).length+"個不一樣的車牌照"); console.log("*******************************下面是生成的車牌照詳細*******************************"); console.log(JSON.stringify(tempLicensePlateObj)); console.log("*******************************同一個車牌照出現屢次的詳細:開始*******************************"); for (var key in tempLicensePlateObj) { if (tempLicensePlateObj.hasOwnProperty(key)) { if(tempLicensePlateObj[key]>1){ console.log("車牌號:【"+key+"】生成了"+tempLicensePlateObj[key]+"次"); } } } console.log("*******************************同一個車牌照出現屢次的詳細:結束*******************************");
爲了生成重複車牌照的機率大,第一次測試這裏縮小了取值範圍:dom
看一下測試結果,重複率仍是很高的,那麼怎麼生成一個不重複的車牌照呢?我想了一個笨方法:就是將已經存在車輛牌照做爲參數傳遞給獲取車輛牌照的方法,返回以前作一下判斷,若是數組中包含了就遞歸獲取,直到獲取到一個不重複的,下面看一下測試二的代碼:
測試
var getRangeRandomNumber = function(num1,num2){ num1 = Number.isInteger(num1) ? num1: 0; num2 = Number.isInteger(num2) ? num2: 0; var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2); return Math.round(Math.random() * (maxNum - minNum)) + minNum; }; // 獲取隨機車牌 var getRandomLicensePlate2=(function f(excludeArr){ if(!Array.isArray(excludeArr))excludeArr=[]; //獲取車牌照的邏輯 var strProvinceShorter="京"; var strNumberLetter="12345"; var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)]; for(var i=0;i<5;i++){ tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)]; } if(excludeArr.indexOf(tempRetLicensePlate)>=0){ tempRetLicensePlate = f(excludeArr); } else { excludeArr.push(tempRetLicensePlate); } return tempRetLicensePlate; }); var tempLicensePlateObj={},licensePlateCounter=Math.pow(5,5),tempAllLicensePlates=[]; for(var i=1;i<=licensePlateCounter;i++){ var temp = getRandomLicensePlate2(tempAllLicensePlates); if(tempLicensePlateObj[temp]){ tempLicensePlateObj[temp]++; } else{ tempLicensePlateObj[temp]=1; } } console.log("想要獲取"+licensePlateCounter+"個不一樣的車牌照"); console.log("結果生成了"+Object.getOwnPropertyNames(tempLicensePlateObj).length+"個不一樣的車牌照"); console.log("*******************************下面是生成的車牌照詳細*******************************"); console.log(JSON.stringify(tempLicensePlateObj)); console.log("*******************************同一個車牌照出現屢次的詳細:開始*******************************"); for (var key in tempLicensePlateObj) { if (tempLicensePlateObj.hasOwnProperty(key)) { if(tempLicensePlateObj[key]>1){ console.log("車牌號:【"+key+"】生成了"+tempLicensePlateObj[key]+"次"); } } } console.log("*******************************同一個車牌照出現屢次的詳細:結束*******************************");
結果想到啊,棧溢出了……我都懷疑個人遞歸有問題,再看下一個測試結果ui
此次獲取數量(最大值減5)比棧溢出的那次少了5次,就不報錯了,接下來我又縮小取值範圍,改爲了四位數,看一下結果spa
此次測試也沒有問題,最後兩次沒有問題是否是說明我寫的遞歸沒有問題……是否是真的由於內存裝不下了???有哪位大神知道這是爲何或者有更好的獲取車輛牌照的方法,還請指點一下,謝謝設計
下面粘一下最終的代碼:code
var getRangeRandomNumber = function(num1,num2){ num1 = Number.isInteger(num1) ? num1: 0; num2 = Number.isInteger(num2) ? num2: 0; var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2); return Math.round(Math.random() * (maxNum - minNum)) + minNum; }; var getRandomLicensePlate=(function f(excludeArr){ if(!Array.isArray(excludeArr))excludeArr=[]; // 生成一個隨機車聯牌照 var strProvinceShorter="京津冀晉蒙遼吉黑滬蘇浙皖閩贛魯豫鄂湘粵桂瓊渝川黔滇藏陝甘青寧新港澳臺"; var strNumberLetter="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var tempRetLicensePlate=strProvinceShorter[getRangeRandomNumber(strProvinceShorter.length-1)]; for(var i=0;i<6;i++){ tempRetLicensePlate+=strNumberLetter[getRangeRandomNumber(strNumberLetter.length-1)]; } // 判斷這個車聯牌照是否存在 if(excludeArr.indexOf(tempRetLicensePlate)>=0){ tempRetLicensePlate = f(excludeArr); } else { excludeArr.push(tempRetLicensePlate); } return tempRetLicensePlate; });
最後又用這個測試了一下,生成100000個沒問題:orm
var tempLicensePlateObj={},licensePlateCounter=100000,tempAllLicensePlates=[]; for(var i=1;i<=licensePlateCounter;i++){ var temp = getRandomLicensePlate(tempAllLicensePlates); if(tempLicensePlateObj[temp]){ tempLicensePlateObj[temp]++; } else{ tempLicensePlateObj[temp]=1; } } console.log(tempAllLicensePlates.length); console.log("想要獲取"+licensePlateCounter+"個不一樣的車牌照"); console.log("結果生成了"+Object.getOwnPropertyNames(tempLicensePlateObj).length+"個不一樣的車牌照"); console.log("*******************************下面是生成的車牌照詳細*******************************"); console.log(JSON.stringify(tempLicensePlateObj)); console.log("*******************************同一個車牌照出現屢次的詳細:開始*******************************"); for (var key in tempLicensePlateObj) { if (tempLicensePlateObj.hasOwnProperty(key)) { if(tempLicensePlateObj[key]>1){ console.log("車牌號:【"+key+"】生成了"+tempLicensePlateObj[key]+"次"); } } } console.log("*******************************同一個車牌照出現屢次的詳細:結束*******************************");
又測了一下,生成1000000個,直接直接卡死了……算了,就到這裏吧!