大小随机唯一数字

时间:2018-04-10 00:41:25

标签: javascript arrays random unique lodash

我想知道获得一个特定大小的数组的最简洁方法是什么,具有独特的随机数。

我得到这样的随机数字:

times(4, () => random(30, 95));

然而,这不是唯一的。我可以使用uniq来过滤它,但我需要保证数组长度为4。而我想以lodash的方式做到这一点。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我知道这不是" lodash方式",但它保证了唯一性,并允许您使用与之前使用的相同的参数。它也比需要通过数组进行二进制或线性搜索的方法更好地扩展,因为set.has()平均为O(1),而不是O(log(n))或O(n)。



function uniqRandom (times, ...args) {
  const set = new Set()

  while (times > 0) {
    const rand = _.random(...args)

    if (!set.has(rand)) {
      set.add(rand)
      times--
    }
  }

  return Array.from(set)
}
 
console.log(uniqRandom(4, 30, 33));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我从功能编程的角度解决了这个问题。 refillRandom是一个递归函数,它检查剩余生成的项目数,并再次调用自身,直到达到所需的项目数。

如果Errormin随机数之间的距离大于所需的唯一项,则在生成序列时不可能会抛出max。抛出错误比等待永远更好。

&#13;
&#13;
const generator = (min, offset) => () =>
    Math.floor(Math.random() * offset + min);

const refillRandom = (list, min, max, times) => {
  const offset = max - min,
    num = times - list.length;
  if (times > offset) {
    throw new Error("Imposible to generate it");
  }
  
  const result = _.uniq(_.times(num, generator(min,offset)));
  if (result.length < num) {
    return result.concat(
      refillRandom(list, min, max, num - result.length)
      );
  }
  return result;
}

const r = refillRandom([], 30, 95, 4);

console.log(r);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
&#13;
&#13;

编辑:我找到了另一个解决方案,我保留了生成数字的有序数组并递增生成的数字,以便将其映射到尚未生成的数字。这样我只能随机调用指定的times

&#13;
&#13;
const randomGenerator = (min, offset, generated, times) => {
  if (!times || !offset) return generated;

  var number = Math.floor(Math.random() * offset + min);
  const len = generated.length;
  for (var i = 0; i < len; i++) {
    if (generated[i] <= number) {
      number++;

    } else {
      generated.splice(i, 0, number);
      return randomGenerator(min, offset - 1, generated, times - 1);
    }
  }
  generated[i] = number;
  return randomGenerator(min, offset - 1, generated, times - 1);

};


const r = randomGenerator(30, 95 - 30, [], 12);

console.log(r);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

很容易...

const uniqRandomNumbers  = _.sampleSize(_.range(30, 95), 4);
console.log(uniqRandomNumbers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>