Look into reservoir sampling: https://en.m.wikipedia.org/wiki/Reservoir_sampling Answer from hippyup on reddit.com
🌐
Reddit
reddit.com › r/rust › what's the best way to shuffle an iterator?
r/rust on Reddit: What's the best way to shuffle an iterator?
April 7, 2023 -

I need to get some random distinct elements inside a range. I don't need to shuffle all the items, so collecting the iterator into a `vec` and calling the ` shuffle` method on it is not desirable. Is there a way to iterate over the range in random order and only get the first `n` items?

EDIT with some context:
I have arbitrarily large collections of `BigInt` numbers and I need to retrieve `n` values in a range from `0` to numbers even of hundreds or thousands of bits. I cannot collect 1 googol items in a `Vec` only to retrieve some tenths or hundreds values. Of course, I could assume that the probability of getting the same number twice is negligible in this specific case but, since the range is arbitrary large I could also have a range of 10 numbers and I must take 9 of them. As a general solution I have started getting random numbers in the target range and manually check if this has been already taken in a previous iteration but I was looking for a lazy solution that could avoid unnecessary checks or allocations.

🌐
Rust
docs.rs › shuffled-iter
shuffled_iter - Rust
The actual iterator which iterates over, in random order, all u32s smaller than or equal to a given maximum value. ... This trait may be used to obtain an instance of ShuffledIter.
Discussions

[Solved] Efficient rust random shuffle of?
I have a Vec. I want to randomly shuffle it in place. Google suggests: iterator - How do I create a Vec from a range and shuffle it? - Stack Overflow extern crate rand; use rand::{thread_rng, Rng}; fn main() { let mut vec: Vec = (0..10).collect(); let slice: &mut [u32] = &mut vec; ... More on users.rust-lang.org
🌐 users.rust-lang.org
12
0
February 20, 2019
iterator - How do I create a Vec from a range and shuffle it? - Stack Overflow
Thank you for your answer. Unfortunately, I pasted your code into the Rust Playground (play.rust-lang.org) and discovered that thread_rng().shuffle is now deprecated. Do you know how we're supposed to shuffle a vector now? More on stackoverflow.com
🌐 stackoverflow.com
How can I, using stable rust, mutably iterate over a random shuffle?
This is a follow up to a previous question. I ended up taking the previous solution and updating it to use Rayon for parallel computation. The code now looks like this all_orgs.par_chunks_mut(48).for_each(|chunk: &mut … More on users.rust-lang.org
🌐 users.rust-lang.org
0
0
January 17, 2024
[feature request] shuffle
Shuffle {} } The Shuffle iterator would create a buffer (Vec::with_capaci... More on github.com
🌐 github.com
1
November 6, 2017
🌐
GitHub
github.com › rust-random › rand › issues › 826
Shuffle Iterator · Issue #826 · rust-random/rand
June 17, 2019 - Background What is your motivation? In a game AI, I'd like to use a random permutation of a vector. However, the order is only used in an iterator and discarded afterwards. Feature request I&#3...
Author   ThomasdenH
🌐
Rust Programming Language
users.rust-lang.org › help
[Solved] Efficient rust random shuffle of? - help - The Rust Programming Language Forum
February 20, 2019 - Google suggests: iterator - How do I create a Vec from a range and shuffle it? - Stack Overflow extern crate rand; use rand::{thread_rng, Rng}; fn main() { let mut vec: Vec = (0..10).collect(); let slice: &mut [u32] = &mut vec; ...
Top answer
1 of 3
133

Rand v0.6.0

The Rng::shuffle method is now deprecated; rand::seq::SliceRandom trait should be used. It provides the shuffle() method on all slices, which accepts an Rng instance:

// Rust edition 2018 no longer needs extern crate

use rand::thread_rng;
use rand::seq::SliceRandom;

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    vec.shuffle(&mut thread_rng());
    println!("{:?}", vec);
}

See it on Playground.

Original answer

You're very close. This should work:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice: &mut [u32] = &mut vec;

    thread_rng().shuffle(slice);
}

&mut [T] is implicitly coercible to &[T], and you annotated the slice variable with &[u32], so the slice became immutable: &mut [u32] was coerced to &[u32]. mut on the variable is not relevant here because slices are just borrows into data owned by someone else, so they do not have inherited mutability - their mutability is encoded in their types.

In fact, you don't need an annotation on slice at all. This works as well:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice = vec.as_mut_slice();

    thread_rng().shuffle(slice);
}

You don't even need the intermediate variable:

extern crate rand;

use rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    thread_rng().shuffle(&mut vec);
}

You should read The Rust Programming Language as it explains the concepts of ownership and borrowing and how they interact with mutability.


2 of 3
20

You can use shuffle like this:

extern crate rand;

use rand::Rng;

fn main() {
    let mut vec: Vec<usize> = (0..10).collect();
    println!("{:?}", vec);
    rand::thread_rng().shuffle(&mut vec);
    println!("{:?}", vec);
}
🌐
Rust
docs.rs › shuffled-iter › latest › shuffled_iter › struct.ShuffledIter.html
ShuffledIter in shuffled_iter - Rust
The actual iterator which iterates over, in random order, all u32s smaller than or equal to a given maximum value. An instance of this struct may be obtained via the ShuffletIterGen trait.
🌐
Rust Rand
rust-random.github.io › book › guide-seq.html
Sequences - The Rust Rand Book
Rand implements a few common random operations on sequences via the IteratorRandom and SliceRandom traits. ... SliceRandom::partial_shuffle: partial shuffle; useful to extract amount random elements in random order
🌐
Timnn
timnn.github.io › shuffled-iter
shuffled_iter - Rust
We cannot provide a description for this page right now
Find elsewhere
🌐
Lib.rs
lib.rs › crates › shuffled-iter
shuffled-iter
September 4, 2016 - Uses old Rust 2015 · #2 in #random-order · 29 downloads per month · MIT license · 11KB 236 lines · This crate provides methods to iterate over a group of values in random order, without allocation and shuffling them all.
🌐
Piston
docs.piston.rs › imageproc › rand › seq › trait.IteratorRandom.html
rand::seq::IteratorRandom - Rust
Collects amount values at random from the iterator into a supplied buffer. Although the elements are selected randomly, the order of elements in the buffer is neither stable nor fully random. If random ordering is desired, shuffle the result.
🌐
Rust Programming Language
users.rust-lang.org › t › how-can-i-using-stable-rust-mutably-iterate-over-a-random-shuffle › 105457
How can I, using stable rust, mutably iterate over a random shuffle? - The Rust Programming Language Forum
January 17, 2024 - This is a follow up to a previous question. I ended up taking the previous solution and updating it to use Rayon for parallel computation. The code now looks like this all_orgs.par_chunks_mut(48).for_each(|chunk: &mut [Organism]|{ for i in 0 .. chunk.len() { let (left, others) = chunk.split_at_mut(i); let (middle, right) = others.split_at_mut(1); let org1 = &mut middle[0]; //process left for org2 in left { single_match_up(org1, org2); ...
🌐
Programming Idioms
programming-idioms.org › idiom › 10 › shuffle-a-list › 410 › rust
Shuffle a list, in Rust
shuffle($x); var Iter,rr: integer; [...] for Iter := 0 to high(x) do begin rr := random(high(x))+1; tmp := x[Iter]; x[Iter] := x[rr]; x[rr] := tmp; end; use List::Util 'shuffle'; @shuffled = shuffle(@x); import random · random.shuffle(x) Demo · Doc · from random import shuffle ·
🌐
Rust
docs.rs › rand › latest › rand › seq › trait.IteratorRandom.html
IteratorRandom in rand::seq - Rust
If random ordering is desired, shuffle the result. The length of the returned vector equals amount unless the iterator contains insufficient elements, in which case it equals the number of elements available. Complexity is O(n) where n is the length of the iterator.
🌐
Rust Documentation
doc.rust-lang.org › stable › std
Results for shuffle - Rust
February 16, 2019 - The option and result modules define optional and error-handling types, Option<T> and Result<T, E>. The iter module defines Rust’s iterator trait, Iterator, which works with the for loop to access collections.
🌐
Rust
docs.rs › shuffle
Crate shuffle - Rust
This crate aims to provide good abstractions to shuffle collections when all you have is just a source of randomness.
🌐
GitHub
github.com › TimNN › shuffled-iter
GitHub - TimNN/shuffled-iter: Iterate through a set of values in random order without allocating them all
Iterate through a set of values in random order without allocating them all - TimNN/shuffled-iter
Author   TimNN
🌐
GitHub
github.com › bluss › rust-itertools › issues › 231
[feature request] shuffle · Issue #231 · rust-itertools/itertools
November 6, 2017 - Shuffle {} } The Shuffle iterator would create a buffer (Vec::with_capacity(buffer_size)) and have two states: empty buffe...
Author   lorepozo
🌐
Hacker News
news.ycombinator.com › item
Meanwhile, in the much more complicated Rust, all but four of those are one-line... | Hacker News
February 24, 2021 - vec.splice(i..i, std::iter::repeat(0).take(length)); This replaces the values in range `i..i` (an empty range starting at i) with `length` copies of `0` · Don't program when tired, kids