JS genereert willekeurige boolean

Eenvoudige vraag, maar ik ben geïnteresseerd in de nuances hier.

Ik genereer willekeurige booleans met behulp van de volgende methode die ik zelf heb bedacht:

const rand = Boolean(Math.round(Math.random()));

Telkens wanneer random()verschijnt, lijkt het erop dat er altijd een valkuil is – het is niet echt willekeurig, het wordt aangetast door het een of ander, enz. Dus ik zou graag willen weten:

a) Is bovenstaande de beste manier om dit te doen?

b) Overdenk ik dingen?

c) Denk ik te weinig na over dingen?

d) Is er een betere/snellere/elegantere manier die ik niet ken?

(Ook enigszins geïnteresseerd als B en C elkaar uitsluiten.)

Bijwerken

Als het een verschil maakt, gebruik ik dit voor de beweging van een AI-personage.


Antwoord 1, autoriteit 100%

Je kunt Math.random()rechtstreeks vergelijken met 0.5, aangezien het bereik van Math.random()[0, 1)(dit betekent ‘in het bereik 0 tot 1 inclusief 0, maar niet 1’). Je kunt het bereik opdelen in [0, 0.5)en [0.5, 1).

var random_boolean = Math.random() < 0.5;

// Example
console.log(Math.random() < 0.1); //10% probability of getting true
console.log(Math.random() < 0.4); //40% probability of getting true
console.log(Math.random() < 0.5); //50% probability of getting true
console.log(Math.random() < 0.8); //80% probability of getting true
console.log(Math.random() < 0.9); //90% probability of getting true

Snippet uitvouwen


Antwoord 2, autoriteit 6%

Als uw project lodashheeft, kunt u:

_.sample([true, false])

U kunt ook uw eigen voorbeeldfunctie gebruiken (bron):

const sample = arr => arr[Math.floor(Math.random() * arr.length)];

Antwoord 3, autoriteit 3%

Voor een cryptografisch veiligere waarde kunt u crypto.getRandomValuesin moderne browsers.

Voorbeeld:

var randomBool = (function() {
  var a = new Uint8Array(1);
  return function() {
    crypto.getRandomValues(a);
    return a[0] > 127;
  };
})();
var trues = 0;
var falses = 0;
for (var i = 0; i < 255; i++) {
  if (randomBool()) {
    trues++;
  }
  else {
    falses++;
  }
}
document.body.innerText = 'true: ' + trues + ', false: ' + falses;

Snippet uitvouwen


Antwoord 4, autoriteit 3%

!Math.round(Math.random());


Antwoord 5, autoriteit 2%

Ik ben erg onder de indruk van Kelvins antwoord. Ik zou graag een redelijk vergelijkbare maar enigszins verbeterde oplossing willen voorstellen.

var randomBoolean = Math.random() < 0.5;

Deze oplossing is wat meer voor de hand liggend om te lezen, omdat het getal aan de rechterkant van <u de kans aangeeft om truete krijgen in plaats van false, wat natuurlijker is om te begrijpen. Ook is <één symbool korter dan >=;


Antwoord 6

Potentieel snellere oplossingen…

Bitwise-operatorbenadering dacht ik net aan Math.random() + .5 >> 0of ~~(Math.random() + .5). Hier is een prestatietestom zelf te beoordelen.

let randomBoolean = Math.random() + .5 >> 0;                 //chance of true
const randomBoolean = chance => Math.random() + chance >> 0; //chance of true

De bitsgewijze operatoren zijn in dit geval in wezen hetzelfde als het gebruik van Math.trunc()of Math.floor(), daarom is dit ook mogelijk Math.trunc(Math.random() + .5).

let randomBoolean = Math.trunc(Math.random() + .5);
const randomBoolean = chance => Math.trunc(Math.random() + chance);

Andere, meer gebruikelijke oplossingen

De meest gebruikelijke manier om willekeurige boolean te krijgen is waarschijnlijk een vergelijkende benadering zoals Math.random() >= .5van Kelvins antwoordof Math.random() < .5;van Arthur Khazbs’s antwoord, geven ze feitelijk true & vals, en niet 1 & 0.

let randomBoolean = Math.random() >= .5;                 //chance of false
const randomBoolean = chance => Math.random() >= chance; //chance of false
let randomBoolean = Math.random()  < .5;                 //chance of true
const randomBoolean = chance => Math.random() < chance;  //chance of true

De enige reden om de Math.round(Math.random())-aanpak te gebruiken is eenvoud en luiheid.


Antwoord 7

Wat dacht je van deze?

return Math.round((Math.random() * 1) + 0) === 0;

Other episodes