前幾天記錄了一下表單生成器(Form Builder)之表單數據存儲結構mongodb篇,之後便想著偽造一些數據。為什麼要偽造數據呢?說來慚愧,因為拖拉拽設計表單以及表單對應的列表的PC端和移動端該顯示哪些欄位並且是否支持搜索列印(即表單的列表配置)等一系列配置都還沒有做,還有就是前面只說了表單相關 ...
前幾天記錄了一下表單生成器(Form Builder)之表單數據存儲結構mongodb篇,之後便想著偽造一些數據。為什麼要偽造數據呢?說來慚愧,因為拖拉拽設計表單以及表單對應的列表的PC端和移動端該顯示哪些欄位並且是否支持搜索列印(即表單的列表配置)等一系列配置都還沒有做,還有就是前面只說了表單相關的設計,設計完了之後就是要使用(錄入數據等)對應的這些也還沒有做……總之就是現在只有數據結構,但是又想寫一下查詢,所以只能偽造一些數據。又想著這些數據儘量真實,所以就想寫點代碼來偽造數據。在寫代碼的時候,想隨機生成一個車輛牌照,所以就有了這篇筆記。
我去,說的太多了,趕緊進入主題。
其實結合上篇筆記:獲取一個隨機數,之後生成一個車輛牌照還是挺簡單的:首先隨機獲取一個省份,然後在數字和字母中隨機獲取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("*******************************同一個車牌照出現多次的詳細:結束*******************************");
為了生成重覆車牌照的概率大,第一次測試這裡縮小了取值範圍:
看一下測試結果,重覆率還是很高的,那麼怎麼生成一個不重覆的車牌照呢?我想了一個笨方法:就是將已經存在車輛牌照作為參數傳遞給獲取車輛牌照的方法,返回之前做一下判斷,如果數組中包含了就遞歸獲取,直到獲取到一個不重覆的,下麵看一下測試二的代碼:
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("*******************************同一個車牌照出現多次的詳細:結束*******************************");
結果想到啊,棧溢出了……我都懷疑我的遞歸有問題,再看下一個測試結果
這次獲取數量(最大值減5)比棧溢出的那次少了5次,就不報錯了,接下來我又縮小取值範圍,改成了四位數,看一下結果
這次測試也沒有問題,最後兩次沒有問題是不是說明我寫的遞歸沒有問題……是不是真的因為記憶體裝不下了???有哪位大神知道這是為什麼或者有更好的獲取車輛牌照的方法,還請指點一下,謝謝
下麵粘一下最終的代碼:
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個沒問題:
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個,直接直接卡死了……算了,就到這裡吧!