Idiom #158 Random sublist

Create a new list y from randomly picking exactly k elements from list x.

It is assumed that x has at least k elements.
Each element must have same probability to be picked.
Each element from x must be picked at most once.
Explain if the original ordering is preserved or not.

``import std.random;``
``auto y = randomSample(x, k);``
``(def y (->> x shuffle (take k)))``
``using System.Collections.Generic;``
``````Random rnd = new Random();
List<int> y = x.OrderBy(r => rnd.Next()).Take(k).ToList();
``````
``````allocate (sample(k))
do i=1,k
sample(i) = x(i)
end do
do i=k+1,n
call random_number(a)
j = 1 + int(i*a)
if (j .le. k) sample(j) = x(i)
end do``````
``import "math/rand"``
``````y := make([]T, k)
perm := rand.Perm(len(x))
for i, v := range perm[:k] {
y[i] = x[v]
}``````
``import System.Random (randomRIO)``
``````randomSample :: Int -> [a] -> IO [a]
randomSample 0 x = pure []
randomSample k x = do
i <- randomRIO (0, length x - 1)
let (a, e:b) = splitAt i x
l <- randomSample (k-1) (a ++ b)
pure (e : l)``````
``````const idx = x.map((item, i) => i);
while (y.length < k) {
const i = parseInt(Math.random() * idx.length, 10);
y.push(x[[idx[i]]]);
idx.splice(i, 1);
}``````
``````import java.util.List;
import java.util.ArrayList;
import java.util.Collections;``````
``````public static <T> List<T> randomSublist(List<T> x, int k) {
List<T> y = new ArrayList<>(x);
Collections.shuffle(y);
return y.subList(0, k);
}``````
``\$y = array_intersect_key(\$x, array_flip(array_rand(\$x, \$k)));``
``uses Types, Math;``
``````function RandArr(Max: Integer): TIntegerDynArray;
var
i, j, temp: Integer;
begin
SetLength(Result, Max+1);
for i := Low(Result) to High(Result) do Result[i] := i;
i := Length(Result);
while i > 0 do
begin
Dec(i);
j := RandomRange(0,i);
temp := Result[i];
Result[i] := Result[j];
Result[j] := temp;
end;
end;

var
Idx: TIntegerDynArray;
begin
Idx := RandArr(High(X));
SetLength(Y, k);
for i := 0 to k-1 do Y[i] := X[Idx];
end.``````
``use List::Util qw(shuffle head);``
``my @y = head \$k, shuffle @x;``
``import random``
``y = random.sample(x, k)``
``y = x.sample(k)``
``use rand::prelude::*;``
``````let mut rng = &mut rand::thread_rng();
let y = x.choose_multiple(&mut rng, k).cloned().collect::<Vec<_>>();``````
``y := x shuffled first: k.``

programming-idioms.org