Skip to content

Instantly share code, notes, and snippets.

@jrmoran
Created March 18, 2011 01:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrmoran/875470 to your computer and use it in GitHub Desktop.
Save jrmoran/875470 to your computer and use it in GitHub Desktop.
/*
Excenlente,
unas observaciones.
*/
var items =
Array(
{ valor:"A", probabilidad: (5/10) },
{ valor:"B", probabilidad: (1/10) },
{ valor:"C", probabilidad: (1/10) },
{ valor:"D", probabilidad: (1/10) },
{ valor:"E", probabilidad: (2/10) }
);
function obtenerLetraProbabilidad() {
var random = Math.random();
var base=0;
for(var i=0;i<items.length;i++) {
if(random>=base && random<(base+items[i].probabilidad)) {
return items[i].valor; // devuelve valor si esta dentro del rango especificado
} else {
base += items[i].probabilidad;
}
}
}
console.log( obtenerLetraProbabilidad() );
/*
Debido a lexical scoping durante compilation time La funcion obtenerLetraProbabilidad() sabe sobre
la existencia del array items un nivel arriba. Esto puede dar problemas cuando la complexidad del codigo aumenta.
(http://blog.dreasgrech.com/2009/12/lexical-scoping-in-javascript.html). Para evitar futuras molestias, podriamos
hacer los siguientes cambios
a) Pasar items como argumento a la funcion obtenerLetraProbabilidad()
*/
console.log('Implementaciones\n');
console.log('*************** 1)');
// declaration
function obtenerLetraProbabilidad2(items) {
var random = Math.random();
var base=0;
for(var i=0;i<items.length;i++) {
if(random>=base && random<(base+items[i].probabilidad)) {
return items[i].valor; // devuelve valor si esta dentro del rango especificado
} else {
base += items[i].probabilidad;
}
}
}
// call
var letra = obtenerLetraProbabilidad2(items)
console.log(letra);
// Tambien podriamos ejecutarlo de la siguinete manera
letra = obtenerLetraProbabilidad2([
{ valor:"F", probabilidad: (5/10) },
{ valor:"G", probabilidad: (1/10) },
{ valor:"H", probabilidad: (1/10) },
{ valor:"I", probabilidad: (1/10) },
{ valor:"J", probabilidad: (2/10) }
]);
console.log(letra);
/*
b) Construir una factory function que abstraiga la complejidad. Aqui ya estamos hablando de construir APIs. Esto nos
permitiria modificar el estado de la collecion que mantene nuestras letras y sus probabilidades, al mismo tiempo
ofrecemos a nuestros usuarios un API publica y evitamos que modifiquen la collecion directamente.
*/
var probabilityBuilder = function(){
var items = []; // array
return{
add: function(v, w) {
items.push({
valor: v,
weight: w
});
},
get:function(){
var random = Math.random();
var base=0;
for(var i=0;i<items.length;i++) {
if(random>=base && random<(base+items[i].weight/this.total())) {
return items[i].valor; // devuelve valor si esta dentro del rango especificado
} else {
base += items[i].weight/this.total();
}
}
},
total: function(){
var total = 0;
for(var i=0, t=items.length; i<t;i++){
total += items[i].weight;
}
return total;
},
debug: function(){
console.log('<Debug=========')
console.log(items);
console.log('totalWeight: ' + this.total());
console.log('=========Debug/>')
}
}
}();
console.log('\n*************** 2)');
probabilityBuilder.add('A',5);
probabilityBuilder.add('B',1);
probabilityBuilder.add('C',1);
probabilityBuilder.add('D',1);
probabilityBuilder.add('E',2);
var letra = probabilityBuilder.get();
probabilityBuilder.debug();
console.log(letra);
/*Tambien simplificamos la manera de ingresar probabilidades, el usuario solo tendria que ingresar el weight de la
letra, las probabilidades se ajustarian de acuerdo a las letras agregadas*/
console.log('Agregando letras');
probabilityBuilder.add('F',1);
probabilityBuilder.add('G',4);
probabilityBuilder.add('H',5);
probabilityBuilder.add('I',3);
var letra = probabilityBuilder.get();
probabilityBuilder.debug();
console.log(letra);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment