Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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
221,325 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,059 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,059 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.