从阵列中获取随机唯一的问题

时间:2016-10-12 22:04:50

标签: javascript jquery

请您看看这个演示,让我知道如何从汽车阵列中获取唯一的选择

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>

3 个答案:

答案 0 :(得分:1)

将其实现为生成器使得使用它非常好。注意,这种实现不同于需要首先对整个输入数组进行混洗的实现。

  

sample功能可以懒惰地工作,每次迭代会为您提供 1 随机项目,直至您要求的N项目。这很好,因为如果你只想要 1000 列表中的 3 项目,你就不必先触摸所有1000个项目。

&#13;
&#13;
// 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]
&#13;
&#13;
&#13;

我选择以不改变输入数组的方式实现sample,但你很容易认为变异实现是有利的。

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

&#13;
&#13;
// 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]
&#13;
&#13;
&#13;

由于数组输入变异,

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

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

也许我想从1,000,000个随机数列表中得到第一个素数。

  • &#34;我应该抽样多少?&#34; - 您不必指定
  • &#34;我是否必须首先找到所有素数,然后选择随机素数?&#34; - 不。

因为我们正在使用生成器,所以此任务很简单

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

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

答案 1 :(得分:0)

你走了。简单的代码。

&#13;
&#13;
var random = 0, cars = ["Saab", "Volvo", "BMW"], newCars = [];

while (newCars.length < 3) {
  random = Math.floor(Math.random() * 3);
  if (newCars.indexOf(cars[random]) == -1) {
    newCars.push(cars[random]);
  }
}

console.log(newCars);
&#13;
&#13;
&#13;

答案 2 :(得分:-1)

试试这个:

function RandomUnique(inputArray){
  var ia = inputArray;
  if(!(ia instanceof Array)){
    throw new Error('inputArray must be an instanceof Array');
  }
  this.unique = function(){
    return ia.splice(Math.random()*ia.length, 1)[0];
  }
  this.getArray = function(){
   return ia;
  }
}
var ru = new RandomUnique(yourArray);
console.log(ru.unique());
console.log(ru.unique());