Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

How do i add to a certain element in an array a less likely accurance to be picked by Math.random?

question in title. let’s say i have an array of names : const names = [״steve”,”daniel”,”david”]; and because “david” is a vip member i want him to have a better chance not to get picked by Math.random()

Steven Parker

Steven Parker
Steven Parker
229,582 Points

:bookmark: I was alerted by your tag, but it looks like Owen beat me to it and left a very nice answer already!

That makes a good point, try letting the whole community provide an answer for a while (say 24 hours or so) before you tag anyone specific, there's plenty of folks willing to help.

2 Answers

Owen Bell
Owen Bell
8,060 Points

Math.random() doesn't take any arguments, so it can't be directly modified to skew its approximately uniform distribution.

For this particular example, I would imagine one simple way to approach this is to use a conditional statement to determine whether or not your VIP should be picked, and if not, randomly select from the remaining names. For example, say there should be a 1 in 10 chance of picking your VIP:

const choice = (Math.random() < 0.1) ? names[2] : names[Math.floor(Math.random() * 2)];

The ternary operator first calls .random() on the Math object to return a decimal to check the odds for selecting a VIP: if it's less than 0.1, which occurs 10% of the time, the condition will evaluate to true and the ternary operator will return names[2], or "David". Otherwise, approximately 90% of the time, the condition evaluates to false and one of the other names is randomly selected to be returned instead.

Obviously implementing just this approach on its own will get messy quickly. It doesn't even work after just one simple change has been made: how would you select "Daniel" if that was the VIP string without referring to it by name? You might want to consider building two separate arrays, stdNames and vipNames, so that you can do this instead:

const names = ["Steve", "Daniel", "David"];
const vipNames = ["David"] ;
const stdNames = names.filter(name => !vipNames.includes(name));

const choice = (Math.random() < 0.1) ? vipNames[Math.floor(Math.random() * vipNames.length)] : stdNames[Math.floor(Math.random() * stdNames.length)];

Using this code you can define what your VIP names are within their own array and filter them out from the rest of the names so that you have two data sets to work with in your operator.

thanks for the reply! can u modify this to be with simple if statement in exchange of the ternary expression and can i explain the last line more in depth?

Owen Bell
Owen Bell
8,060 Points

Sure thing! First, here are both of those code chunks refactored as if statements:

const choice;
if (Math.random() < 0.1) {
  choice = names[2];
} else {
  choice = names[Math.floor(Math.random() * 2)];
}
const names = ["Steve", "Daniel", "David"];
const vipNames = ["David"] ;
const stdNames = names.filter(name => !vipNames.includes(name));

const choice;
if (Math.random() < 0.1) {
  choice = vipNames[Math.floor(Math.random() * vipNames.length)];
} else {
  choice = stdNames[Math.floor(Math.random() * stdNames.length)];
}

In the second script, the stdNames array is created by calling the .filter method on names, excluding any name found in the vipNames array (!vipNames.includes(name)). When the if statement runs, the condition evaluates the result of calling .random() on the Math object to determine which of the two arrays, stdNames and vipNames, it should be selecting a name from. After that condition evaluates to true or false, the statement randomly selects a name from the appropriate list.