JavaScript generate random number except some values

后端 未结 13 1639
野性不改
野性不改 2021-01-05 11:26

I\'m generating random numbers from 1 to 20 by calling generateRandom(). How can I exclude some values, say 8 and 15?

function generateRandom(mi         


        
相关标签:
13条回答
  • 2021-01-05 11:50

    I have answered a similar question for Java: Generate random numbers except certain values. I just copy and paste the answer as follows.

    Actually, we do not need to use contains(random) with a while loop.

    To simplify the question, let's see what happens if we only have one excluding value. We can split the result to 2 parts. Then the number of possible values is range-1. If the random number is less than the excluded value, just return it. Otherwise, we could add 1.

    For multiple excluding values, We can split the result set into size+1 parts, where size means the number of excluding values. Then the number of possible values is range-size. Then we sort excluding values in ascending order. If random number is less than the excluding value minus i, then we just return the random number add i, where i is the index of the the excluding value.

    public int generateRandomNumberWithExcepts(int start, int end, List<Integer> excepts) {
        int size = excepts.size();
        int range = end - start + 1 - size;
        int randNum = random.nextInt(range) + start;
        excepts.sort(null); // sort excluding values in ascending order
        int i=0;
        for(int except : excepts) {
            if(randNum < except-i){
                return randNum + i;
            }
            i++;
        }
        return randNum + i;
    }
    
    0 讨论(0)
  • 2021-01-05 11:50

    You could take an offset for random values greater or equal than zerow ith a sorted (ascending) array and return a sum with adjusted random value.

    const
        getRandomWithoutZero = (lower, upper, gaps) => () => {
            const r = Math.floor(Math.random() * (upper - lower + 1 - gaps.length) + lower);
            return gaps.reduce((s, g) => s + (s >= g), r);
        },
        random = getRandomWithoutZero(-9, 9, [-3, 0, 4]),
        count = {};
    
    for (let i = 0; i < 1.6e6; i++) {
        const r = random();
        count[r] = (count[r] || 0) + 1;
    }
    
    console.log(count);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    0 讨论(0)
  • 2021-01-05 11:54

    You can simply do like this

    function generatedRandExclude(showed,max) {
         let randNo = -1;
         while(showed.length < max) {
            	randNo = Math.floor(Math.random() * Math.floor(max));	
             	if(!showed.includes(randNo)) {
                	showed.push(randNo);
                 	break;
              }
         }
         return randNo;
    }
    
    let showed = [];
    function run() {
        console.log(generatedRandExclude(showed,6));
    }
    run();
    run();
    run();
    run();

    generatedRandExclude generate random number excluded using array showed.

    0 讨论(0)
  • 2021-01-05 11:57

    Here is a really stupidly overcomplicated solution...

            <script>
        var excludedNumbers = [];
        excludedNumbers.push(8);
        excludedNumbers.push(15);
        excludedNumbers.push(10);
    
        var array = generateExclude(excludedNumbers, 1, 20);
    
        function generateExclude(excludedNumbers, min, max){
            var newNumbers = [];
            for(var i = min; i <= max; i++) {
                for(var j = 0; j < excludedNumbers.length; j++) {
                    var checker = $.inArray(i, excludedNumbers)
                    if(checker > -1){
    
                    }else{
                        if($.inArray(i, newNumbers)<= -1){
                            newNumbers.push(i); 
                        }
    
                    }
                };
            };
            return newNumbers;
        }
        function generateRandomNumbers(items){
            var num = items[Math.floor(Math.random()*items.length)];;
            return num;
        }
        console.log(generateRandomNumbers(array))
        </script>
    
    0 讨论(0)
  • 2021-01-05 11:58

    Here is a slightly modified answer that is similar to all the others but it allows your to pass a single or an array of failing numbers

    function generateRandom(min, max, failOn) {
        failOn = Array.isArray(failOn) ? failOn : [failOn]
        var num = Math.floor(Math.random() * (max - min + 1)) + min;
        return failOn.includes(num) ? generateRandom(min, max, failOn) : num;
    }
    
    0 讨论(0)
  • 2021-01-05 11:58

    I've read through all these answers and they differ a lot in philosophy, so I thought I might add my very own 2 bits, despite of this question having an answer, because I do think there is a better and more elegant way of approaching this problem.

    We can make a function that takes min, max and blacklist as parameters and outputs a random result without using recursion (and with close to 0 if statements):

    const blrand = function(min, max, blacklist) { if(!blacklist) blacklist = [] let rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; let retv = 0; while(blacklist.indexOf(retv = rand(min,max)) > -1) { } return retv; }

    usage: let randomNumber = blrand(0, 20, [8, 15]);

    0 讨论(0)
提交回复
热议问题