Как генерировать случайные числа без повторения javascript

Я использую следующий код, который генерирует случайное число от 0 до Totalfriends, я хотел бы получить случайные числа, но они не должны повторяться. Есть идеи как?

Это код, который я использую

FB.getLoginStatus(function(response) {
    var profilePicsDiv = document.getElementById('profile_pics');
FB.api({ method: 'friends.get' }, function(result) {

     // var result =resultF.data;
   // console.log(result);
   var user_ids="" ;
   var totalFriends = result.length;
   // console.log(totalFriends);
   var numFriends = result ? Math.min(25, result.length) : 0;
  // console.log(numFriends);
   if (numFriends > 0) {
      for (var i=0; i<numFriends; i++) {
        var randNo = Math.floor(Math.random() * (totalFriends + 1))
        user_ids+= (',' + result[randNo]);
         console.log(user_ids);

          }
        }
        profilePicsDiv.innerHTML = user_ids;
      });
});

person Yahoo    schedule 25.05.2012    source источник
comment
Вы должны использовать Math.floor(Math.random() * totalFriends), иначе вы иногда будете выходить за конец массива   -  person Eric    schedule 25.05.2012


Ответы (4)


Вот функция, которая возьмет n случайных элементов из array и вернет их на основе перетасовки Фишера-Йейтса. Обратите внимание, что это изменит аргумент array.

function randomFrom(array, n) {
    var at = 0;
    var tmp, current, top = array.length;

    if(top) while(--top && at++ < n) {
        current = Math.floor(Math.random() * (top - 1));
        tmp = array[current];
        array[current] = array[top];
        array[top] = tmp;
    }

    return array.slice(-n);
}

Предполагая, что ваш код работает так, как я думаю, у вас уже есть массив идентификаторов пользователей:

var random10 = randomFrom(friendIds, 10);
person Eric    schedule 25.05.2012
comment
У меня есть обновление полного кода, я фактически получаю список идентификаторов из тех списков идентификаторов, которые я выбираю случайным образом 25. - person Yahoo; 25.05.2012
comment
Итак, я должен добавить эту функцию randomFrom на страницу, а затем вызвать ее вместо randNo? - person Yahoo; 25.05.2012

  1. создать массив (например, yourarray) чисел в диапазоне [1..totalfriends]
  2. перетасовать массив (например, используя javascript-реализацию алгоритма Fisher-Yates)
  3. внутри for (от 0 до yourarray.length - 1) сделайте pop() из массива (или просто получите элемент n-th), чтобы вы каждый раз получали другое число

Таким образом, вы избежите дублирования номеров.

person Fabrizio Calderan    schedule 25.05.2012
comment
Я не знаком с функцией pop(), как я могу реализовать ее здесь. ? - person Yahoo; 25.05.2012
comment
pop уже реализован в javascript. возвращает последний элемент массива - person Fabrizio Calderan; 27.05.2012

Я бы выполнил случайные итерации, создал массив со всеми вашими числами, например:

var friendIndexes = [];

for (var i=0; i<numFriends; i++)
{
   friendIndexes.push(i);
}

Затем, когда у вас есть массив всех чисел, я бы выполнил некоторое количество итераций, может быть, 1000, где вы генерируете два случайных числа и меняете значения в этих индексах.

for (var s = 0; s<1000; s++)
{
    var rnd1 = Math.floor(Math.random() * (numFriends + 1);
    var rnd2 = Math.floor(Math.random() * (numFriends + 1);

    // Swap the two values (remember to use a temp variable)
    var tmp = friendIndexes[rnd1];
    friendIndexes[rnd1] = friendIndexes[rnd2];
    friendIndexes[rnd2] = tmp;
}

По сути, вы их перемешиваете, и в результате вы получите числа в случайном порядке.

person NibblyPig    schedule 25.05.2012
comment
Идея хороша, но тасование Фишера-Йейтса более эффективный способ перетасовать массив. - person Matthew Crumley; 25.05.2012
comment
Я обновил полный код, на самом деле я получаю список идентификаторов из этого списка идентификаторов, которые я выбираю случайным образом 25 - person Yahoo; 25.05.2012

Возьмите большое число, которое не делится на numFriends, или просто большое простое число (например, единица: 702038, 727699, 992700, 1201046, 1232255, 2312734, 3136255, 4235414, 6090515), затем идет

var result=[] ;
var K=Math.floor((Math.random()*bigUnNumFreindsDivider) ;

for (var i=0; i<numFriends; i++)
{
    result[i]=(i*bigUnNumFreindsDivider+K)%numFreinds ;
}

Это должно работать нормально.

person Aurel    schedule 25.05.2012