如何确保数组中随机插入的数字不重复?

时间:2012-01-30 21:50:47

标签: javascript

我一直试图这么做但是每次都失败了。我有var rand = Math.floor(Math.random() * 5);log.push(rand);。为了确保它不重复任何值,我尝试:

function dontRepeat() {
    var g = 0;
    for (var i = 0; i < log.length; i++) {
        if (log[log.length - i] == rand) g++;
        if (g > 1) {
            rand = Math.floor(Math.random() * n);
            dontRepeat();
        }
    }
}

请帮我找出问题所在。

5 个答案:

答案 0 :(得分:1)

为什么不这样做:

function unique_randoms(length, maximum) {
  var numbers = [];
  var test;

  for (var i = 0; i < length; i++) {
    do {
      test = Math.floor(Math.random() * maximum);
    } while (numbers.indexOf(test) != -1);

    numbers.push(test);
  }

  return numbers;
}

演示:http://jsfiddle.net/ZSE2w/

你真的不需要做递归。另外,请确保length <= maximum

答案 1 :(得分:0)

为什么不将值存储在字典/集内的日志中,并继续检查您正在推送的每个新值,无论它是否已插入字典/集中。如果没有太多的值,那么这个解决方案就不会浪费那么多空间。

答案 2 :(得分:0)

跟踪已使用的数字作为对象的属性(在这种情况下,您可能会从常量属性查找中受益),(未经测试):

function getNonDuplicateRandoms(n, max) {
  var used={}, numbers=[], rand, i;
  if (n > max) throw new Error("n > max");
  for (i=0; i<n; i++) {
    do {
      rand = Math.floor(Math.random() * max);
    } while (used[rand]);
    numbers.push(rand);
    used[rand] = true;
  }
  return numbers;
}

答案 3 :(得分:0)

首先制作有序数组,您可以获得重复的免费列表:

A = [];
for(i=0; i<n; i++) A[i]=i;

然后洗牌:

for(i=0; i<n; i++) {
  r = Math.floor(Math.random() * (i + 1));
  swap = A[i];
  A[i] = A[r];
  A[r] = swap;
}

现在将您需要的内容提升到n。如果n非常大,则会占用大量内存,在这种情况下,使用indexOf方法测试已经使用的内容可能更有效。但是,这种方法很慢,并且随着您需要的项目数量接近n而变慢。

答案 4 :(得分:-1)

最明显的解决方案 - 记录所有结果并保持随机生成数字 - 是无效的,因为它是随机的,而且据你所知,它可以随机生成与你已经生成的相同的数字,接近永恒(非常不可能,但仍然)。

最简单,最有效的方法,至少在可管理的可能范围内,是为了做出一系列可能的选择:

var choices = [1, 2, 3, 4];

然后使用Array.sort()

对数组进行洗牌
// Randomization function, to sort randomly
var random_function = function(x, y) { return 0.5 - Math.random(); }

choices.sort(random_function);

或者,在一行中:

choices.sort(function(x,y) { return 0.5 - Math.random(); }

最后,将数组切片为仅获取 n 结果:

var result = choices.slice(0, n);