> pick | shuffle | pair <
// Klistra in en lista, dra vinnare, blanda ordningen eller dela in personer i grupper - allt i din webbläsare
Välj N slumpmässiga objekt
Dra valfritt antal vinnare från din lista. Utan återläggning för unika vinnare, eller med återläggning för viktade dragningar.
Opartisk Fisher-Yates-blandning
Ordnar om hela listan med den klassiska Knuth-blandningen. Varje permutation är lika sannolik - inga naiva sorteringsknep här.
Dela in i grupper
Dela upp en lista i par, trios eller valfri gruppstorlek. Perfekt för pararbete, kodgranskningsrotationer eller hemlig tomte-parningar.
Reproducerbarhet med seed
Ange en seed-sträng för en deterministisk dragning. Samma seed plus samma lista ger alltid samma resultat - delbart och verifierbart.
// OM SLUMPVÄLJAREN
Så fungerar det:
Detta verktyg använder Fisher-Yates- (även kallad Knuth-) blandningen: gå igenom arrayen från sista index till första, och byt vid varje steg det aktuella elementet mot ett på ett likformigt slumpmässigt tidigare index. Detta ger en opartisk, likformig permutation i O(n)-tid. Det naiva tricket array.sort(() => Math.random() - 0.5) är partiskt eftersom JavaScript-sorteringsjämförelser måste vara transitiva - slumpmässiga jämförelser bryter mot det och snedvrider fördelningen. För dragningar utan seed hämtar vi entropi från window.crypto.getRandomValues. När du anger en seed-sträng hashar vi den med cyrb53 till ett 53-bitars heltal och driver sedan en mulberry32-PRNG så att identiska seeds ger identiska, reproducerbara resultat.
Algoritm:
for i = n-1 down to 1: j = randInt(0, i); swap(a[i], a[j]) - unbiased Fisher-Yates
Standarder & referenser:
- >Web Crypto API (W3C) - crypto.getRandomValues för kryptografiskt stark slumpmässighet
- >Fisher-Yates-blandning (1938), populariserad av Donald Knuth i The Art of Computer Programming vol. 2
- >mulberry32 - liten, snabb, väl fördelad seed-PRNG av Tommy Ettinger
- >cyrb53 - 53-bitars sträng-hash av bryc, används för att omvandla en seed-sträng till ett numeriskt PRNG-tillstånd
Vanliga användningsområden:
- >Utlottningar, lotterier och att utse en slumpmässig vinnare bland bidragen
- >Namndragningar i klassrummet och val av elever för spontana frågor
- >Parning av idrottslag, parträning och turneringsträd
- >Tilldelning av kodgranskare i ett ingenjörsteam
- >Urval av stickprov för A/B-tester och randomiserade enkätkohorter
- >Hemlig tomte-par, julklappsbyten och lunchkompisar i teamet
- >Slumpmässiga testindata och fuzzing-seeds för QA
- >Gruppbaserat beslutsfattande och avgörande vid lika resultat
- >Urval av låtsasjury och randomiserade intervjupaneler
- >Lotteriliknande dragningar för lokala evenemang och priser
Relaterade verktyg:
- >Slumptalsgenerator — den textbaserade motsvarigheten: välj tal i ett intervall med samma seed-reproducerbarhetsprimitiver
- >UUID-generator — slumpmässiga v4-identifierare när du behöver ett unikt ogenomskinligt id snarare än en vinnare från en lista
- >Lösenordsgenerator — kryptografiskt slumpmässiga strängar med kontroll över teckenuppsättningen för tokens och inloggningsuppgifter
- >randompickerwheel.app — lyckohjulsgränssnitt som komplement till denna textväljare, perfekt för livedragningar inför publik, frågor i klassrummet och avslöjanden på skärmen
// EXEMPEL PÅ DRAGNINGAR
Utlottning — välj 3 vinnare bland 50 bidrag
> input:
alice@x.com
bob@x.com
carlos@x.com
…(50 rader totalt)
> config:
Läge=Pick N, Antal=3, Tillåt dubbletter=off, Seed=(tom)
> output:
1. carlos@x.com
2. priya@x.com
3. wei@x.com
Blanda en lista med 10 namn för en presentationsordning
> input:
Alice
Bob
Charlie
Dana
Evelyn
Farouk
Gabriela
Hiroshi
Isabella
Jamal
> config:
Läge=Shuffle, Seed=(tom)
> output:
1. Hiroshi
2. Alice
3. Farouk
4. Jamal
5. Dana
6. Evelyn
7. Bob
8. Isabella
9. Gabriela
10. Charlie
Dela in en klass på 12 elever i grupper om 2
> input:
S01
S02
S03
S04
S05
S06
S07
S08
S09
S10
S11
S12
> config:
Läge=Pair Up, Gruppstorlek=2, Seed=class-2026-05-02
> output:
Grupp 1: S07, S02
Grupp 2: S11, S04
Grupp 3: S09, S12
Grupp 4: S01, S06
Grupp 5: S03, S10
Grupp 6: S08, S05
Reproducerbar dragning med seed — kör två gånger med samma seed, få samma vinnare
> input:
alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel
> config:
Läge=Pick N, Antal=2, Seed=launch-day, Tillåt dubbletter=off
> output:
Körning 1: 1. echo
2. bravo
Körning 2: 1. echo
2. bravo (identiskt — med seed)
// VARFÖR NAIVT .SORT() ÄR PARTISKT
En vanlig enradsblandning är arr.sort(() => Math.random() - 0.5). Den ser elegant ut, ryms på en rad och känns slumpmässig — men den resulterande permutationsfördelningen är långt ifrån likformig. ECMAScript-specifikationen kräver att jämförelsefunktioner är deterministiska och transitiva: om a < b och b < c, så a < c. En slantsinglings-jämförare bryter mot det kontraktet, och motorns sorteringsimplementering besöker jämförelsepar enligt ett ojämnt mönster.
V8 (Chrome, Node) använder Timsort; äldre motorer använde quicksort eller mergesort. Varje implementering besöker en annan delmängd av jämförelsepar och återanvänder cachade jämförelser på olika sätt. Som Mike Bostock visade empiriskt (bost.ocks.org/mike/shuffle/compare.html) ger den naiva sorteringen kraftigt partiska resultat där vissa permutationer dyker upp flera gånger oftare än andra — oacceptabelt för en utlottning, en A/B-hink eller någon dragning som måste vara rättvis.
Den korrekta algoritmen är Fisher-Yates (Knuth-blandning): gå igenom arrayen från sista index ner till första, och byt vid varje steg det aktuella elementet mot ett valt likformigt slumpmässigt bland index 0..i. Den körs i O(n), använder O(1) extra utrymme och ger bevisligen varje permutation med lika sannolikhet.
// BAD: NOT uniformly random
const shuffled = arr.sort(() => Math.random() - 0.5);
// GOOD: Fisher-Yates (Knuth) shuffle
function shuffle(arr) {
const a = arr.slice();
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
// IMPLEMENTERA DET SJÄLV
Vill du bygga din egen väljare eller granska vår? Det här är exakt de primitiver som denna sida använder — små, beroendefria och identiska med det som körs i din webbläsare när du klickar på PICK. Kopiera dem rakt in i ett Node-skript eller en annan webbapp.
// Fisher-Yates shuffle (uniform, O(n))
function shuffle(arr, rng = Math.random) {
const a = arr.slice();
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(rng() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
// Pick N without replacement (shuffle then slice)
function pickN(arr, n, rng = Math.random) {
if (n > arr.length) {
throw new Error('n exceeds list size');
}
return shuffle(arr, rng).slice(0, n);
}
// mulberry32 seeded PRNG + cyrb53 string hash
// cyrb53: turn a seed string into a 53-bit integer
function cyrb53(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed;
let h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
// mulberry32: tiny seeded PRNG -> [0, 1)
function mulberry32(a) {
return function () {
a |= 0; a = (a + 0x6D2B79F5) | 0;
let t = a;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
// Build a seeded picker:
const h = cyrb53('my-seed', 1);
const state = (h ^ Math.floor(h / 4294967296)) >>> 0;
const rng = mulberry32(state);
const winners = pickN(['alice', 'bob', 'carlos'], 2, rng);
>> vanliga frågor
F: Hur genereras slumpmässigheten?
S: När ingen seed anges använder vi window.crypto.getRandomValues, webbläsarens kryptografiskt säkra slumptalsgenerator som bygger på Web Crypto API. Det är samma entropikälla som används för kryptografiska nycklar och tokens, så den är mer än stark nog för lotterier och blandningar. När du anger en seed härleder vi deterministiskt ett 53-bitars tillstånd via cyrb53-sträng-hashen och matar in det i en mulberry32-PRNG så att dragningen blir reproducerbar.
F: Kan jag få samma resultat två gånger med en seed?
S: Ja. Skriv vilken sträng som helst i SEED-fältet - ett datum, ett tävlingsnamn, en hash, vad som helst. Samma seed kombinerad med samma indatalista och samma läge ger alltid exakt samma utdata. Detta är ovärderligt för transparenta utlottningar där du vill publicera seedet i förväg och låta deltagarna verifiera dragningen, eller för ingenjörsrotationer som måste vara reproducerbara mellan maskiner.
F: Vad är skillnaden mellan Pick N och Shuffle?
S: Pick N väljer en delmängd av storlek N från din lista, valfritt med återläggning (dubbletter tillåtna). Shuffle returnerar hela listan omordnad - inga objekt tas bort eller upprepas, bara omarrangeras. Använd Pick N när du bara vill ha några få vinnare bland många bidrag; använd Shuffle när varje objekt fortfarande ska delta men i en ny slumpmässig ordning, som en presentationskö eller spellista.
F: Är array.sort(() => Math.random() - 0.5) verkligen slumpmässig?
S: Nej, den är partisk. ECMAScript-specifikationen kräver att sorteringsjämförelser är deterministiska och transitiva (om a < b och b < c så a < c). En slumpmässig jämförare bryter mot det kontraktet, och olika JavaScript-motorer kör olika underliggande sorteringsalgoritmer (TimSort, mergesort, quicksort) som interagerar med den slumpmässiga jämföraren på olika sätt. Resultatet är en ojämn fördelning där vissa permutationer dyker upp långt oftare än andra. Fisher-Yates är den korrekta algoritmen.
F: Kan jag para ihop en lista med ett udda antal?
S: Ja. Pair Up-läget blandar din lista med Fisher-Yates och delar sedan in den efter den valda gruppstorleken. Om totalen inte går jämnt upp blir den sista gruppen mindre och märks tydligt som en restgrupp i utdatan. För en udda lista kan du antingen acceptera en ensam post, öka gruppstorleken eller lägga till ett platshållarnamn som "bye" före dragningen.
F: Laddas min lista upp någonstans?
S: Nej. Detta verktyg är 100 % på klientsidan - din lista, din seed och utdatan lämnar aldrig din webbläsare. Det finns inget serveranrop, ingen loggning och ingen analys av indata. Du kan koppla bort internet efter att sidan laddats och varje knapp fungerar fortfarande. Ladda om sidan och datan är borta för gott.
F: Finns det en visuell lyckohjulsversion av detta verktyg?
S: För en interaktiv namnhjulsupplevelse med animation, ljudeffekter och ett stort visuellt avslöjande, se randompickerwheel.app. Det är en kompletterande produkt med fokus på livedragningar inför publik och skärmdelning. Denna sida är en textfokuserad väljare inriktad på stora listor, reproducerbara dragningar med seed, CSV-export och parning - användbar när du behöver ett snabbt deterministiskt svar i stället för en presentation.