从数组获取随机唯一 [英] Getting random unique from array

查看:76
本文介绍了从数组获取随机唯一的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作这个演示.如何才能从汽车阵列中获得唯一的选择

I am working on this demo. How can I get ONLY unique selection(s) from the array of cars

var random = Math.floor(Math.random() * (3 - 1 + 1)) + 1;

var cars = ["Saab", "Volvo", "BMW"];
for ( var i = 0,l = cars.length; i <random; i++ ) {
   var item = cars[Math.floor(Math.random()*cars.length)];
   console.log(item);
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

推荐答案

将其实现为生成器使其可以很好地工作.请注意,此实现不同于要求首先对整个输入数组进行混洗的实现.

Implementing this as a generator makes it pretty nice to work with. Note, this implementation differs from ones that require the entire input array to be shuffled first.

sample函数的工作方式比较懒惰,每次迭代为您提供 1 个随机项,最多为您要的N个项目.很好,因为如果您只想从 1000 列表中选择 3 个项目,则不必先触摸全部1000个项目.

This sample function works lazily, giving you 1 random item per iteration up to N items you ask for. This is nice because if you just want 3 items from a list of 1000, you don't have to touch all 1000 items first.

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let ys = xs.slice(0);
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield ys.splice(i,1)[0];
    n--; len--;
  }
}

// example inputs
let items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

// get 3 random items
for (let i of sample(3) (items))
  console.log(i); // f g c

// partial application
const lotto = sample(3);
for (let i of lotto(numbers))
  console.log(i); // 3 8 7

// shuffle an array
const shuffle = xs => Array.from(sample (Infinity) (xs))
console.log(shuffle(items)) // [b c g f d e a]

我选择以不变异输入数组的方式实现sample,但是您可以轻松地认为变异实现是有利的.

I chose to implement sample in a way that does not mutate the input array, but you could easily argue that a mutating implementation is favourable.

例如,shuffle函数可能希望对原始输入数组进行突变.或者,您可能希望在不同的时间从相同的输入中进行采样,从而每次都更新输入.

For example, the shuffle function might wish to mutate the original input array. Or you might wish to sample from the same input at various times, updating the input each time.

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield xs.splice(i,1)[0];
    n--; len--;
  }
}

// deal :: [Card] -> [Card]
const deal = xs => Array.from(sample (2) (xs));

// setup a deck of cards (13 in this case)
// cards :: [Card]
let cards = 'A234567890JQK'.split('');

// deal 6 players 2 cards each
// players :: [[Card]]
let players = Array.from(Array(6), $=> deal(cards))

console.log(players);
// [K, J], [6, 0], [2, 8], [Q, 7], [5, 4], [9, A]

// `cards` has been mutated. only 1 card remains in the deck
console.log(cards);
// [3]

sample不再是 pure 函数,但是在某些情况下(如上所示),它可能更有意义.

sample is no longer a pure function because of the array input mutation, but in certain circumstances (demonstrated above) it might make more sense.

我选择生成器而不是仅返回数组的函数的另一个原因是,您可能要继续采样直到某些特定条件.

Another reason I chose a generator instead of a function that just returns an array is because you may want to continue sampling until some specific condition.

也许我想要1,000,000个随机数列表中的第一个素数.

Perhaps I want the first prime number from a list of 1,000,000 random numbers.

  • 我应该采样多少?" –您不必指定
  • 我必须先找到所有素数,然后选择随机素数吗?" –不.
  • "How many should I sample?" – you don't have to specify
  • "Do I have to find all the primes first and then select a random prime?" – Nope.

因为我们正在使用发电机,所以这项任务很简单

Because we're working with a generator, this task is trivial

const randomPrimeNumber = listOfNumbers => {
  for (let x of sample(Infinity) (listOfNumbers)) {
    if (isPrime(x))
      return x;
  }
  return NaN;
}

这将一次连续采样1个随机数x,检查其是否为质数,然后返回x.如果在找到素数之前已用尽数字列表,则返回NaN.

This will continuously sample 1 random number at a time, x, check if it's prime, then return x if it is. If the list of numbers is exhausted before a prime is found, NaN is returned.

这篇关于从数组获取随机唯一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆