简体   繁体   中英

Best way to randomly pull from an array?

I have a website that will give you a random fact from Wikipedia when you click a big red button. I have heard from a few people that they are getting certain facts repeatedly, even though there are over 200.

The big red button has onclick="giveafact()" which triggers this function:

function giveafact(){ //instead of relisting all array items here, add all the other arrays to this one
  var factsList= foodFactsList.concat(musicFactsList,historyFactsList,popFactsList,sportsFactsList,technologyFactsList,televisionFactsList,miscFactsList);
  randomFact = Math.floor(Math.random()*factsList.length);
  document.getElementById("total").innerHTML=factsList.length;
  document.getElementById("fact").innerHTML=factsList[randomFact];
  updateShareLinks();
  return false;
}

Basically, I have 8 different arrays of facts as you can see in var factsList above. This is so the user can filter by fact. By default, there is no filter so all lists are concatenated.

If it helps, the full .js file is here: http://thewikifix.com/scripts/script.js . These random "give a fact" functions start at about line 442, with the arrays above them. (Pardon the messy code, I know I mix jQuery and Javascript a lot.)

The site is http://thewikifix.com , if it helps anyone to look at all the code.

I'm just trying to see if there's a way to better randomize the facts than I currently have, maybe by adding a function that won't allow a fact to show up twice in a row, or something similar.

Any suggestions would be great!

Edit - Additional thoughts: Thanks for the answers so far. Is there a way to remove an item from an array once it has been picked via the Math.random function so it just wouldn't show up again at all (unless the page was refreshed)? If so, once all items were removed from the array is there a way to reset the array to its original state without the user having to refresh? Thanks.

"Random" and "varied" are, to some extent, conflicting. With 200 facts, and one selected randomly each time, it becomes more likely than not that you'll see a repeat after getting only a couple dozen or so (this is known as the "Birthday Problem").

A simple approach is to store a seed and an index on the client. The seed is set once, and the index is incremented after each fact access. To get a "random" fact, seed a PRNG with the seed, use the PRNG to shuffle the list of facts, then get the fact at the given index in the shuffled list. When you run out, pick a new seed and reset the index.

Here's what I would do:

n = 0 - Find a random fact
  add that fact to a new array (arr)
  display fact

n + 1 - Find a random fact
  check arr using lodash for that facts existence
  display or find a new fact, based on result of above

--OR--

you could take the arr and use lodash's _.shuffle() to mix them up and display them in order.

https://lodash.com/docs

I love using lodash for collection and array operations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM