Source address: https://juejin.im/post/5ae413946fb9a07a9c03f7f7
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> class RandomSplit { constructor(num) { // actual total this.num = this.getNum(num); // gain try { this.multiple = this.num.toString().split('.')[1].length; } catch (e) { this.multiple = 0; } // total number for integer operations this.calcNum = this.num * Math.pow(10, this.multiple); } // Determine whether it is a number (take "is-number") isNumber(num) { let number = +num; if ((number - number) !== 0) { return false; } if (number === num) { return true; } if (typeof num === 'string') { if (number === 0 && num.trim() === '') { return false; } return true; } return false; } // get the number getNum(num, defaultNum = 0) { return this.isNumber(num) ? (+num) : defaultNum; } //The number of equal shares, the accuracy of the equal share, whether to directly return the enlarged integer average(n, precision, isInt) { precision = Math.floor(this.getNum(precision, 0)); n = Math.floor(this.getNum(n)); let calcNum = this.calcNum * Math.pow(10, precision < 0 ? 0 : precision); // The number of copies exceeds the calculated total number after magnification, that is, the case of insufficient points if (n > calcNum) { return []; } else { let index = 0; // average let avg = Math.floor(calcNum / n); // remainder let rest = calcNum % n; // remaining number fill interval let gap = Math.round((n - rest) / rest) + 1; // original average array let result = Array(n).fill(avg); // while (rest > 0) { index = (--rest) * gap; result[index >= n ? (n - 1) : index]++; } // return the zoomed result array if (isInt) { return result; } // Return the result array that meets the precision requirements after processing return result.map((item) => { return (item / Math.pow(10, this.multiple + precision)); }); } } // The number of random divisions, the division accuracy split(n, precision) { n = Math.floor(this.getNum(n)); precision = Math.floor(this.getNum(precision, 0)); // evenly let arr = this.average(n, precision, true); let arrResult = arr.concat(); for (let i = 0; i < arr.length; i++) { //total amount given let num = Math.floor(Math.random() * arr[i]); // Amount to give to left neighbor let numLeft = Math.floor(Math.random() * num); // Amount to give to right neighbor let numRight = num - numLeft; // First and last index processing let iLeft = i === 0 ? (arr.length - 1) : (i - 1); let iRight = i === (arr.length - 1) ? 0 : (i + 1); arrResult[i] -= num; arrResult[iLeft] += numLeft; arrResult[iRight] += numRight; } // shrink to original size return arrResult.map((item) => { return (item / Math.pow(10, this.multiple + precision)); }); } } var r = new RandomSplit (250); console.log(r.average(3)) console.log(r.split(3)) </script> </body> </html>