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
Antwoord 2, autoriteit 6%
Als uw project lodash
heeft, 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.getRandomValues
in 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;
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 true
te 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 >> 0
of ~~(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() >= .5
van 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;