Random Line Picker

Pick random lines from a list or shuffle the whole list into a random order, with draws with or without replacement.

0
Lines available

The one-line shuffle everybody uses is not a shuffle

If you have ever shuffled a list in JavaScript, you have probably written items.sort(() => Math.random() - 0.5). It is short, it looks clever, and it produces a different order every time. It is also badly biased, and this page is a good place to say so, because picking a random line is exactly the job it gets used for.

The reason is that a comparison function is supposed to describe a consistent ordering. This one answers differently every time it is asked about the same pair, so what comes out depends on which comparisons the sorting algorithm happens to make — an implementation detail nobody designed to be random.

Shuffling four items 240,000 times and counting how often each of the 24 possible orders comes up:

MethodChi-square scoreVerdict
sort(() => random - 0.5) 277,269 fails, by four orders of magnitude
Fisher–Yates 31.5 passes

With 23 degrees of freedom, anything above about 44.18 fails at the 0.5% level. Fisher–Yates scores 31.5 and passes comfortably. The sort version scores 277,269. Both methods were measured the same way with the same random source, so the difference is the method and nothing else — and it fails at every random seed we tried.

The bias favours whoever is at the ends of your list

A chi-square score is abstract. Here is the same problem in a form that matters if you are drawing a winner: across six items, how often does each one stay exactly where it started? A fair shuffle leaves each in place one time in six, or 16.7%.

MethodItem 1Item 2Item 3Item 4Item 5Item 6
sort 28.6%26.9%18.1%17.1%23.0%26.5%
Fisher–Yates 16.7%16.8%16.8%16.7%16.7%16.6%

The first and last items are far more likely to stay put than the middle ones — 28.6% against 17.1% here. Fisher–Yates sits flat on 16.7% across every position.

If you are drawing a prize winner, setting a running order, or dealing cards, that is a real advantage handed to whoever happens to be at the top or bottom of the list — and it is invisible, because any single shuffle looks perfectly random.

The fix is three lines. Walk backwards through the list and swap each item with a randomly chosen one at or before it:

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]];
}

That is Fisher–Yates. It is provably uniform, it is faster than sorting, and there is no situation in which the sort version is the better choice.

The picker above uses it, with one refinement. Math.random() is fine for a raffle among friends but it is not unpredictable to anyone determined, so this tool draws from crypto.getRandomValues instead — and rather than reducing that value with %, which reintroduces a small bias of its own whenever the range does not divide evenly, it discards values that fall in the uneven tail and draws again. Two separate sources of bias, both avoidable, both usually left in.

How to use

  1. Paste your list, one item per line.
  2. Choose how many items to pick.
  3. Decide whether an item can be selected more than once.
  4. Deduplicate first if repeated lines are not intentional.
  5. Copy the result, or shuffle the whole list instead.

Frequently asked questions

What is the difference between drawing with and without replacement?

Whether a picked item goes back into the pool. Without replacement each item can be chosen only once, which is what you want for a prize draw or for assigning people to tasks. With replacement allows repeats, which is correct for statistical sampling and wrong for a raffle.

How does the shuffle work?

By a proper shuffle algorithm that gives every possible ordering equal probability, seeded from the browser's cryptographic random source. Naive approaches — sorting by a random comparison function, for instance — produce measurably biased orderings and are a well-known and surprisingly common trap.

Is this fair enough for a prize draw?

For an informal one, entirely. For anything carrying legal or financial weight, use a documented and auditable process instead, since regulated draws carry requirements about verifiability, witnessing and record-keeping that no web page can satisfy.

Why did I get the same item twice?

Either replacement was enabled, or that item genuinely appears more than once in your list. Duplicate lines are treated as separate entries, which doubles that item's chance of selection — deduplicating first is worth doing whenever that is not what you intended.

Can I reproduce a result later?

No, and that is deliberate. Cryptographic randomness has no seed to record, which is exactly the property you want in a draw nobody should be able to predict. Reproducibility requires a seeded generator, which belongs in simulation and testing rather than in a selection.

Does my list get uploaded?

No. Everything happens in your browser, so names, entries and whatever else the list contains stay on your device.

What if my list has blank lines?

Empty lines are skipped rather than treated as entries, so a list pasted from a document with spacing between items behaves as expected. Lines containing only whitespace are treated the same way.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.