0

I'm trying to emulate the functionality of random.choices in the Python standard library, in JavaScript. I tried this code:

function choices(arr, weights = null, k = 1) {
    let out = [];
    if (weights != null) {
        // implemented later
    } else if (k == 1) {
        return arr[Math.floor(Math.random() * arr.length)]
    } else {
        for (let i = 0; i < k; i++) {
            out.push(arr[Math.floor(Math.random() * arr.length)])
        }
        return out;
    }
}

console.log(choices([0,4,9,2], k = 2)

I want the k = 2 part to pass a keyword parameter, like how they work in Python.

But k just shows up as any:

VSCode hovering over the k parameter, saying any.

How can I get the desired effect?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
berriz44
  • 62
  • 1
  • 1
  • 13
  • 1
    In the future, if you are trying to port code or emulate a feature from some other language, please don't tag that language, and try to make it clear what the feature or functionality is for people who don't use that language. This question is fundamentally **about the parameter-passing style, not about Python**; people who are experts in Python have no special advantage in answering it, and will not be interested in learning JavaScript to answer it. In general, multiple language tags should indicate that solving the problem **must** involve writing code in **all** languages mentioned. – Karl Knechtel Jul 26 '23 at 07:15

2 Answers2

1

In JavaScript there is a somewhat related feature, but you have to define the parameter list differently. Think of it as explicitly defining the kwargs dict (in Python terminology). Also the caller must pass an object (dict) to match it. You can make that single parameter optional by assigning a default for it (as a whole):

function choices(arr, {weights=null, k=1}={}) {
    let out = [];
    if (weights != null) {
        // implemented later
    } else if (k == 1) {
        return arr[Math.floor(Math.random() * arr.length)]
    } else {
        for (let i = 0; i < k; i++) {
            out.push(arr[Math.floor(Math.random() * arr.length)])
        }
        return out;
    }
}

console.log(choices([0,4,9,2], {k: 2}));
trincot
  • 317,000
  • 35
  • 244
  • 286
1

You can achieve something similar by passing in an object

function choices({arr, weights = null, k = 1}) {
    let out = [];
    if (weights != null) {
        // implemented later
    } else if (k == 1) {
        return arr[Math.floor(Math.random() * arr.length)]
    } else {
        for (let i = 0; i < k; i++) {
            out.push(arr[Math.floor(Math.random() * arr.length)])
        }
        return out;
    }
}

console.log(choices({arr: [0,4,9,2], k: 2}))

The difference is that you don't have positional arguments anymore, you need to specify the key of each value (in this case arr: [0, 4, 9, 2])

Stichiboi
  • 79
  • 1
  • 5