how to debug this weighted random name picker code

Tags:



Here is the code which will pick a random Name based on the defined weight.

Here is the code:

var rand = function(min, max) {
    return Math.random() * (max - min) + min;
};

var getRandomItem = function(list, weight) {
    var total_weight = weight.reduce(function (prev, cur, i, arr) {
        return prev + cur;
    });

    var random_num = rand(0, total_weight);
    var weight_sum = 0;
    console.log(random_num)

    for (var i = 0; i < list.length; i++) {
        weight_sum += weight[i];
        weight_sum = +weight_sum.toFixed(2);

        if (random_num <= weight_sum) {
            return list[i];
        }
    }

    // end of function
};


var list = [];
var data = [];

data[0] = { Name: "Jack", accuracy: 52, accent: 79, weight: 1 };
data[1] = { Name: "Sara", accuracy: 92, accent: 24, weight: 2 };
data[2] = { Name: "Nick", accuracy: 82, accent: 89, weight: 1 };
data[3] = { Name: "Doe", accuracy: 22, accent: 88, weight: 4 };
data[4] = { Name: "Lee", accuracy: 58, accent: 63, weight: 9 };
data[5] = { Name: "Sasha", accuracy: 69, accent: 42, weight: 5 };

for ( var i=0; i < data.length; i++ ) {
  list.push( data[i] );

}

  console.log(list);

 setInterval(function(){  

 for ( var i=0; i < data.length; i++ ) {
  var random_item = getRandomItem(list[i].Name, list[i].weight);
  console.log(random_item);

}

}, 500);

Unfortunately, the code doesn’t work because of an error:

Uncaught TypeError: weight.reduce is not a function at getRandomItem

I can’t figure it out why this happens.

Note: this will work…

var list = ['javascript', 'php', 'ruby', 'python'];
var weight = [1, 1, 1, 9];
var random_item = getRandomItem(list, weight);
console.log(random_item);

Answer

As others pointed out list and weight parameters have to be arrays. So I’m building two arrays in the following code.

var rand = function(min, max) {
    return Math.random() * (max - min) + min;
};

var getRandomItem = function(list, weight) {
    var total_weight = weight.reduce(function (prev, cur, i, arr) {
        return prev + cur;
    });

    var random_num = rand(0, total_weight);
    var weight_sum = 0;
    console.log(random_num)

    for (var i = 0; i < list.length; i++) {
        weight_sum += weight[i];
        weight_sum = +weight_sum.toFixed(2);

        if (random_num <= weight_sum) {
            return list[i];
        }
    }

    // end of function
};


var list = [];
var weight = [];
var data = [];

data[0] = { Name: "Jack", accuracy: 52, accent: 79, weight: 1 };
data[1] = { Name: "Sara", accuracy: 92, accent: 24, weight: 2 };
data[2] = { Name: "Nick", accuracy: 82, accent: 89, weight: 1 };
data[3] = { Name: "Doe", accuracy: 22, accent: 88, weight: 4 };
data[4] = { Name: "Lee", accuracy: 58, accent: 63, weight: 9 };
data[5] = { Name: "Sasha", accuracy: 69, accent: 42, weight: 5 };

for ( var i=0; i < data.length; i++ ) {
  list.push( data[i].Name );
  weight.push( data[i].weight );
}

  console.log(list);
  console.log(weight);

 setInterval(function(){  

for ( var i=0; i < data.length; ++i ) {
  var random_item = getRandomItem(list, weight);
  console.log(random_item);
}

}, 500);


Source: stackoverflow