Hi,

If I have an array such as arr=[0.6,0.1,0.3]

How can I write pick and index randomly using these numbers in javaScript?

like pick 0, 60% of the times.

1, 10% of the times

2, 30% of the times

Thanks

Hi,

If I have an array such as arr=[0.6,0.1,0.3]

How can I write pick and index randomly using these numbers in javaScript?

like pick 0, 60% of the times.

1, 10% of the times

2, 30% of the times

Thanks

1 Like

I assume that sum of elements = 1.

The idea is to make a new array called `prArr`

in which elements occurs as much times as their probability ratio.

```
let nums = [0.6, 0.1, 0.3]
let lc = 0.1
let randomPick = arr => {
let idx = 0, begin, count, prArr = []
arr.map(val => {
begin = idx
count = val / lc
for(; idx < count + begin; idx++)
prArr[idx] = val
})
let k = Math.floor(Math.random() * prArr.length)
return prArr[k]
}
for(let i = 0; i < 10; i++)
console.log(randomPick(nums))
```

Tip: You can adjust `lc`

to `0.01`

or `0.001`

based upon number of decimals

3 Likes

The idea is good. But you already have the probabilities so why not calculate with them?

You just do a Math.random(); and use this to get the index which correlates to this by using the cumulative probabilities, where every element has a certain area on the number scale from 0.0 up to 1.0 (e.g. element 0 is from 0.0 to 0.6, 1 is from 0.6 to 0.7 and 2 is 0.7 to 1.0):

```
const rnd = Math.random();
const arr = [0.6, 0.1, 0.3]
// The index and the cummulative probability
let index = -1;
let cum = 0;
// We add the cummulative probabilities and search till we get to where rnd is
arr.forEach((e, i) => {
if(rnd >= cum && rnd < cum + e) {
index = i;
}
cum += e;
});
```

Feel free to use also `findIndex()`

method with the same idea behind it:

```
let cum = 0;
const rnd = Math.random();
const arr = [0.6, 0.1, 0.3];
const index = arr.findIndex(e => { cum += e; return rnd < cum && rnd >= cum - e;})
```

(I am sorry for naming the one variable â€ścumâ€ť)

4 Likes

@JaielSoft, another one, based on subtracting elements from random value in each loop

```
let nums = [0.6, 0.1, 0.3]
let randomPick = arr => {
let k = Math.random()
// get the first value that makes "rnd int" negative on subtraction
let res = arr.find(val => (k -= val) < 0)
return res || arr.pop() // else pop the last one
}
for(let i = 0; i < 10; i++)
console.log(randomPick(nums))
```

For one-liners,

```
let randPick = (a, k=Math.random()) => a.find(v => (k -= v) < 0) || a.pop()
```

1 Like

This one line works perfectly in the live example. But I am having trouble implementing it in my code.

what I did is create a function

`randPick = (a, k=Math.random()) =>{ a.find(v => (k -= v) < 0) || a.pop()`

}

Then in the main function that is running I used.

var randNum=this.randPick(percentVector[j]);

console.log(randNum);

For trying it I used

percentVector[j]=[0.5,0.5]

but the results is â€śundefinedâ€ť

sorry if this is a trivial question but I am new at using JavaScript

you used {} in the lambda function so you need to add a `return`

statement. The original code didnt have them and a `return`

is implied.

edit: So if you dont get it the solution:

```
randPick = (a, k=Math.random()) =>{
return a.find(v => (k -= v) < 0) || a.pop();
}
```

(Although I dont like the `(k -= v)`

statement because it doesnâ€™t adhere to general programming principals of making code that is easy to read and doesnâ€™t hold any surprises. Also altering the state of a parameter, that should always be treated as constant, is not the best practice. But if it works out itâ€™s fine. I like short code too after all)

1 Like

Thank you!

you are right the longer code is actually more readable and easier to understand. I preferred the one line because my code already contains multiple nested loops. I am trying to do things with no more loops for things to be faster.