Muszę wygenerować zestaw liczb całkowitych unikalnych (bez duplikatów), a między 0 a daną liczbą.

To jest:

var limit = 10;
var amount = 3;

Jak mogę użyć JavaScript, aby wygenerować 3 unikalne numery od 1 do 10?

52
benhowdle89 5 grudzień 2011, 01:52

11 odpowiedzi

Jak wskazano, że zaakceptowana odpowiedź jest błędna. Oto nieuzasadniający generator PSUDO z praktycznie bez problemów z pamięcią i nr O (N), które są dobre dla 10 000 000 numerów.

Oto Plunkr Wykazanie portu JavaScript poniżej nieintracującego generatora psedo-losowego znalezionego Github.com/preshing/RandomeSklepy.

var RandomSequenceOfUnique = (function() {      
  function RandomSequenceOfUnique(seedBase, seedOffset) {
    var prime = 4294967291,
        residue,
        permuteQPR = function(x) {
      if (x >= prime)
        return x; 
      residue = (x * x) % prime;
      return (x <= prime / 2) ? residue : prime - residue;
    }

    this.next = function() {
      return permuteQPR((permuteQPR(this.index++) + this.intermediateOffset) ^ 0x5bf03635);
    }

    this.index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
    this.intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
  }
  return RandomSequenceOfUnique;
}());

Skonstruuj instancję i wygeneruj numer:

var generator = new RandomSequenceOfUnique(Date.now(), parseInt(Math.random() * 10000));

Korzystanie z generatora:

 var num = generator.next();

Oto artykuł wyjaśniający matematykę za generatorem, Jak wygenerować sekwencję unikalnych losowych liczb całkowitych

2
RamblinRose 29 kwiecień 2017, 14:39
Math.floor(Math.random() * (limit+1))

Math.random() Generuje numer pływającego punktu między 0 a 1, Math.floor() okrąża go do całkowitego.

Mnożąc go przez numer, skutecznie wykonaj zasięg 0..number-1. Jeśli chcesz wygenerować go w zakresie od num1 do num2, wykonaj:

Math.floor(Math.random() * (num2-num1 + 1) + num1)

Aby wygenerować więcej liczb, wystarczy użyć pętli i umieścić wyniki do tablicy lub napisz je bezpośrednio do dokumentu.

19
taras 24 maj 2019, 08:06
Math.floor(Math.random()*limit)+1
3
Pål Brattberg 4 grudzień 2011, 21:54
for(i = 0;i <amount; i++)
{
    var randomnumber=Math.floor(Math.random()*limit)+1
    document.write(randomnumber)
}
2
Tim Cooper 11 marzec 2012, 17:05

Coś takiego

var limit = 10;
var amount = 3;
var nums = new Array();

for(int i = 0; i < amount; i++)
{
    var add = true;
    var n = Math.round(Math.random()*limit + 1;
    for(int j = 0; j < limit.length; j++)
    {
        if(nums[j] == n)
        {
            add = false;
        }
    }
    if(add)
    {
        nums.push(n)
    }
    else
    {
        i--;
    }
}
1
Ash Burlaczenko 4 grudzień 2011, 22:02
var randomNums = function(amount, limit) {
var result = [],
    memo = {};

while(result.length < amount) {
    var num = Math.floor((Math.random() * limit) + 1);
    if(!memo[num]) { memo[num] = num; result.push(num); };
}
return result; }

Wydaje się, że działa, a jego ciągły wygląd duplikatów.

1
Patrik Torkildsen 29 kwiecień 2017, 15:10
/**
 * Generates an array with numbers between
 * min and max randomly positioned.
 */
function genArr(min, max, numOfSwaps){
  var size = (max-min) + 1;
  numOfSwaps = numOfSwaps || size;
  var arr = Array.apply(null, Array(size));

  for(var i = 0, j = min; i < size & j <= max; i++, j++) {
    arr[i] = j;
  }

  for(var i = 0; i < numOfSwaps; i++) {
    var idx1 = Math.round(Math.random() * (size - 1));
    var idx2 = Math.round(Math.random() * (size - 1));

    var temp = arr[idx1];
    arr[idx1] = arr[idx2];
    arr[idx2] = temp;
  }

  return arr;
}

/* generating the array and using it to get 3 uniques numbers */
var arr = genArr(1, 10);
for(var i = 0; i < 3; i++) {
  console.log(arr.pop());
}
0
Rayron Victor 17 czerwiec 2017, 01:12

Myślę, że jest to najbardziej ludzkie podejście (z wykorzystaniem przerwy z podczas pętli), wyjaśniłem to mechanizm w komentarzach.

function generateRandomUniqueNumbersArray (limit) {

    //we need to store these numbers somewhere
    const array = new Array();
    //how many times we added a valid number (for if statement later)
    let counter = 0;

    //we will be generating random numbers until we are satisfied
    while (true) {

        //create that number
        const newRandomNumber = Math.floor(Math.random() * limit);

        //if we do not have this number in our array, we will add it
        if (!array.includes(newRandomNumber)) {
            array.push(newRandomNumber);
            counter++;
        }

        //if we have enought of numbers, we do not need to generate them anymore
        if (counter >= limit) {
            break;
        }
    }

    //now hand over this stuff
    return array;
}

Możesz oczywiście dodać inny limit (swoją ilość) do ostatniego "Jeśli" oświadczenie, jeśli potrzebujesz mniej liczb, ale upewnij się, że jest mniejszy lub równy limitowi samych liczb - w przeciwnym razie będzie to nieskończona pętla.

0
Martin Melichar 20 grudzień 2019, 18:06
const getRandomNo = (min, max) => {
   min = Math.ceil(min);
   max = Math.floor(max);
   return Math.floor(Math.random() * (max - min + 1)) + min; 
}

Ta funkcja zwraca losową liczbę całkowitą między określonymi wartościami. Wartość nie jest niżej niż min (lub następna liczba całkowita większa niż min, jeśli min nie jest liczbą całkowitą) i jest mniejsza niż (ale nie równa) max. Przykład

console.log(`Random no between 0 and 10 ${getRandomNo(0,10)}`)
-1
akash kumar 6 grudzień 2019, 07:16

Oto proste, jednolite rozwiązanie:

var limit = 10;
var amount = 3;

randoSequence(1, limit).slice(0, 3);

Używa Randojs.com, aby wygenerować losowo tasowane tablicę liczb całkowitych od 1 do 10, a następnie odetnie wszystko po trzecim całkowitym . Jeśli chcesz użyć tej odpowiedzi, rzuć to w tagu głowy dokumentu HTML:

<script src="https://randojs.com/1.0.0.js"></script>
-1
Aaron Plocharczyk 22 kwiecień 2020, 20:43
function generateRange(pCount, pMin, pMax) {
    min = pMin < pMax ? pMin : pMax;
    max = pMax > pMin ? pMax : pMin;
    var resultArr = [], randNumber;
    while ( pCount > 0) {
        randNumber = Math.round(min + Math.random() * (max - min));
        if (resultArr.indexOf(randNumber) == -1) {
            resultArr.push(randNumber);
            pCount--;
        }
    }
    return resultArr;
}

W zależności od zasięgu potrzebnych sposobu zwrócenia liczby całkowitej można zmienić na: Ceil (a, b], okrągły [a, b], piętro [a, b), dla (a , b) jest kwestią dodawania 1 do min na podłodze.

5
Bakudan 5 grudzień 2011, 07:05