I have a fixed-size array [T; SIZE]
of values of a type T that is ordered (it implements Ord
, but not necessarily Clone
or Default
). I would like to extract the smallest value of the array and drop all the others.
In nightly rust, I can use array::IntoIter
to achieve that, but if possible, I would like my code to compile on stable.
Currently, I'm using the following (playground):
// Don't call this function if T has a custom Drop implementation or invalid bit patterns
unsafe fn get_min<T: Ord>(mut arr: [T; SIZE]) -> T {
let (idx, _) = arr.iter().enumerate().min_by(|(_, x), (_, y)| x.cmp(y)).unwrap();
unsafe { replace(&mut arr[idx], MaybeUninit::uninit().assume_init()) }
}
Of course, I'm not very happy with that... Is there a solution that is safer, and maybe less verbose ?
There is no way to do this in stable Rust; arrays cannot have values added or removed at runtime; their lengths are fixed at compile time.
Arrays of any size implement the following traits if the element type allows it: Copy. Clone. Debug.
In this article, we will see how to solve Copy An Array in rust code with examples. let arr =["a","b","c"]; // ES6 way const copy = [... arr]; // older method const copy = Array. from(arr);
The length of an array is the number of elements present in the array. We use the len() function to obtain this value.
In the 2021 edition of Rust (available in Rust 1.56 and up), the into_iter()
method on an array returns an iterator over the owned items, so this becomes easy:
fn get_min<T: Ord>(arr: [T; SIZE]) -> T {
arr.into_iter().min().unwrap() // assuming SIZE > 0
}
In earlier versions of Rust, you can move the minimum to the beginning of the array, and then use a slice pattern to move the first element out of the array:
fn get_min<T: Ord>(mut arr: [T; SIZE]) -> T {
for i in 1..SIZE {
if arr[i] < arr[0] {
arr.swap(0, i);
}
}
let [min, ..] = arr;
min
}
(Playground)
Related questions:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With