One possible use case is to sort one array by keys from some other array. It comes up very frequently for me, and for data oriented programming in general. permutation - Rust can do this, but it requires computing intermediate permutation and additional heap space.
I don't see a good way for it to be an external crate, as it would basically have to reimplement the sorting form std.
To avoid internal allocation you could oblige caller to supply a scratch array of [usize; N].
EDIT: Concretely, suppose we added this function to slices
/// for 0 <= i < self.len() move item i to position permutation[i]
/// panics if self.len() != permutation.len()
/// (if possible make that a type constraint)
/// or if permutation is not actually a permutation of 0..self.len()
pub fn permute(&mut self, permutation: &[usize])
then I think the existing <[usize]>::sort_(unstable_)by_key could do the rest of the job?
Though that doesn't guarantee the order of the calls to the key generator (just that it's at most once per item), so you can't just calculate the index inside the closure.
I would love something like that too. I end up with some variations of parallel arrays / structure-of-arrays quite often.
That's technically quite close to sort_by_cached_key, but I almost never end up using actual sort_by_cached_key, because typically I have to build all the keys first using some elaborate process that can't make keys on demand, so I have to make my own "cached_key" storage, but still need the "sort" part.
I'm not sure if |slice, i, j| could optimize out bounds checks. I've tried to make LLVM remove bounds checks in select_nth_unstable and found that length checks fail to propagate across non-trivial conditions.
But something that takes a slice of keys and a slice of values to sort, performs a one-time length check, and then swaps with unsafe indexing under the hood if necessary, would be fine for me.
[values].sort_by_keys(&mut [keys])
// or
[keys].sort_values(&mut [values])
The latter could work with multiple homogeneous parallel arrays via [keys].sort_values(&mut [[values]; N]).
With some hypothetical variadic generics, or enough macro hacks, maybe it could support multiple different parallel arrays [keys].sort_values((&mut [T], &mut [U])).