how to deal with this fundamental error in rust? - rust

im writing a program to convert a number to sorted reversed array of digits.
eg : 23453 -> vec![5,4,3,3,2]
but i got this error! and i cant fix this
error[E0599]: no method named `sorted` found for struct `Chars` in the current scope
--> src/main.rs:2050:25
|
2050 | n.to_string().chars().sorted().map(|no| no.to_digit(10).unwrap() as u32).rev().collect::<Vec<u32>>()
| ^^^^^^ method not found in `Chars<'_>`
error[E0277]: `Vec<u32>` doesn't implement `std::fmt::Display`
here is my code,
fn sorted_rev_arr(n : u32) -> Vec<u32>{
n.to_string().chars().sorted().map(|no| no.to_digit(10).unwrap() as u32).rev().collect::<Vec<u32>>()
}
fn main(){
let random_number = 23453;
println!("the new number in array is {}",sorted_rev_arr(random_number));
}
can anybody help me to resolve this issue ?

There is no sorted method in Rust iterators or Vec. You'll have to collect to a Vec first and then sort it:
fn sorted_rev_arr(n: u32) -> Vec<u32> {
let mut digits = n
.to_string()
.chars()
.map(|no| no.to_digit(10).unwrap() as u32)
.collect::<Vec<u32>>();
digits.sort();
digits.reverse();
digits
}
You can also do a reverse sort in one go:
fn sorted_rev_arr(n: u32) -> Vec<u32> {
let mut digits = n
.to_string()
.chars()
.map(|no| no.to_digit(10).unwrap() as u32)
.collect::<Vec<u32>>();
digits.sort_by(|a, b| b.cmp(&a));
digits
}
Also, you need to use {:?} instead of {} to print a Vec.
Playground

Related

How can I check, at compile-time, that a slice is a specific size?

I'd like to check, at compile-time, that a slice used in a From implementation is a specific size.
(Playground)
#[derive(Debug)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}
impl From<&[u8]> for Pixel {
fn from(arr: &[u8]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}
fn main() {
println!("Hello, world!");
let arr: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
println!("{:.?}", pixels);
}
This is not as specific as I'd like. I'd like to check the arr passed to Pixel::from<&[u8]>() is 3 elements as clearly as possible (at compile time).
Thought of assert!(arr.len()==3), but this checks at runtime.
So I thought maybe I could do the conversion by (Playground):
impl From<[u8; 3]> for Pixel {
fn from(arr: [u8; 3]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}
but this leads to:
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:54
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
= note: required by `from`
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
Similarly I tried From<&[u8; 3]> but same result.
Is there a way to implement from for a specific sized slice?
This is a not a duplicate of How to convert a slice into an array reference? as this question specifically relates to checking at compile-time without runtime performance effects, it is not casting &[u8] to &[u8; 3] rather simply checking at compile time &[u8] has 3 elements (which may be done via using &[u8; 3]). All answers to the aforementioned question incur runtime affects, except I believe this approach in this answer (applied like this) but this does not check at all that the slice is the appropriate length. This question is not specifically about being able to use Pixel::from<[u8;3]> but rather about generally checking the length at compile time, which none of these answers offer or relate to.
You cannot do this at compile time because slice lengths are not known at compile time. That's a big reason that slices exist in the first place. When the length is known at compile time, that's an array.
See also:
What is the difference between a slice and an array?
How to set a Rust array length dynamically?
Take slice of certain length known at compile time
I'd instead write both fallible and infallible conversions:
use std::array::TryFromSliceError;
use std::convert::TryFrom;
#[derive(Debug)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}
impl TryFrom<&[u8]> for Pixel {
type Error = TryFromSliceError;
fn try_from(arr: &[u8]) -> Result<Self, Self::Error> {
<&[u8; 3]>::try_from(arr).map(Self::from)
}
}
impl From<&[u8; 3]> for Pixel {
fn from(arr: &[u8; 3]) -> Self {
Self::from(*arr)
}
}
impl From<[u8; 3]> for Pixel {
fn from(arr: [u8; 3]) -> Self {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}
Then you can convert from an array, allowing for a compile time error, or when you have a slice and don't know the length at compile time, you can attempt to convert and have a run-time error.
In the future, you can use methods like slice::array_chunks to convert a slice into an iterator of arrays. However, there's still the case that the slice wasn't the right length (too long or short) that you have to handle somehow.

How do I get a slice containing all but the Nth element? [duplicate]

I have a function that needs to operate on two parts of a single array.
The purpose is to be able to build an #[nostd] allocator that can return a variable slice of a bigger array to the caller and hang on to the remainder of the array for future allocations.
Here's example code that fails:
fn split<'a>(mut item: &'a mut [i32], place: usize) -> (&'a mut [i32], &'a mut [i32]) {
(&mut item[0..place], &mut item[place..])
}
fn main() {
let mut mem: [i32; 2048] = [1; 2048];
let (mut array0, mut array1) = split(&mut mem[..], 768);
array0[0] = 4;
println!("{:?} {:?}", array0[0], array1[0]);
}
the error is as follows:
error[E0499]: cannot borrow `*item` as mutable more than once at a time
--> src/main.rs:2:32
|
2 | (&mut item[0..place], &mut item[place..])
| ---- ^^^^ second mutable borrow occurs here
| |
| first mutable borrow occurs here
3 | }
| - first borrow ends here
This pattern also can be helpful for in-place quicksort, etc.
Is there anything unsafe about having two mutable references to nonoverlapping slices of the same array? If there's no way in pure Rust, is there a "safe" unsafe incantation that will allow it to proceed?
Is there anything unsafe about having two mutable references to nonoverlapping slices of the same array?
There isn't, but Rust's type system cannot currently detect that you're taking mutable references to two non-overlapping parts of a slice. As this is a common use case, Rust provides a safe function to do exactly what you want: std::slice::split_at_mut.
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])
Divides one &mut into two at an index.
The first will contain all indices from [0, mid) (excluding the index
mid itself) and the second will contain all indices from [mid, len)
(excluding the index len itself).
The final code is:
fn main() {
let mut mem : [i32; 2048] = [1; 2048];
let (mut array0, mut array1) = mem[..].split_at_mut(768);
array0[0] = 4;
println!("{:?} {:?}", array0[0], array1[0]);
}
Wow that was such a perfect match. Thanks for finding this!

How do I perform operations on different numeric types while computing the average in an idiomatic Rust manner?

I tried to implement a small module where I calculate the mean of a vector:
pub mod vector_calculations {
pub fn mean(vec: &Vec<i32>) -> f32 {
let mut sum: f32 = 0.0;
for el in vec.iter() {
sum = el + sum;
}
sum / vec.len()
}
}
As far as I can tell from the compiler error, there are two problems with my code:
error[E0277]: the trait bound `&i32: std::ops::Add<f32>` is not satisfied
--> src/main.rs:6:22
|
6 | sum = el + sum;
| ^ no implementation for `&i32 + f32`
|
= help: the trait `std::ops::Add<f32>` is not implemented for `&i32`
error[E0277]: the trait bound `f32: std::ops::Div<usize>` is not satisfied
--> src/main.rs:9:13
|
9 | sum / vec.len()
| ^ no implementation for `f32 / usize`
|
= help: the trait `std::ops::Div<usize>` is not implemented for `f32`
I'm trying to add a &i32 with a f32 and I'm trying to divide a f32 with an usize.
I could solve the second error by changing the last line to:
sum / (vec.len() as f32)
Is this is actually how a Rust programmer would do this?
Furthermore, I don't really know how to solve the first error. What has to be done and why?
Yes, dereferencing values and converting numeric types is normal in Rust. These conversions help the programmer recognize that edge cases are possible. As loganfsmyth points out:
An i32 can hold values greater than f32 can represent accurately
Unfortunately, the compiler can't tell what's "correct" for your case, so you still have to be on guard.
For what it's worth, I'd write your current implementation using Iterator::sum:
fn mean(items: &[i32]) -> f64 {
let sum: f64 = items.iter().map(|&v| v as f64).sum();
sum / (items.len() as f64)
}
You should also probably handle the case where the input is empty to avoid dividing by zero:
fn mean(items: &[i32]) -> Option<f64> {
let len = items.len();
if len == 0 {
None
} else {
let sum: f64 = items.iter().map(|&v| v as f64).sum();
Some(sum / (len as f64))
}
}
Using the method from What is a good solution for calculating an average where the sum of all values exceeds a double's limits?, but made a bit more iterator-heavy:
fn mean2(ary: &[i32]) -> f64 {
ary.iter().enumerate().fold(0.0, |avg, (i, &x)| {
avg + ((x as f64 - avg) / (i + 1) as f64)
})
}
See also:
Why is it discouraged to accept a reference to a String (&String) or Vec (&Vec) as a function argument?
.iter() returns an &i32 and Rust does not automatically dereference for type conversions — you are currently trying to change the pointer (&) instead of changing what it's pointing to.
Changing your code to look like this is the simplest way to make it work:
pub mod vector_calculations {
pub fn mean(vec: &Vec<i32>) -> f32 {
let mut sum: f32 = 0.0;
for el in vec.iter() {
sum = *el as f32 + sum; // first dereference the pointer, than cast to f32
}
sum / vec.len() as f32 // cast to f32
}
}
But there are some ways to improve this kind of code:
pub mod vector_calculations {
pub fn mean(vec: &[i32]) -> f32 { // accept a slice instead of a vector
// it now allows arrays, slices, and vectors
// but now you can't add or remove items
// during this function call.
let mut sum: i32 = 0; // as the sum is still a whole number, changing the type
// should make it slightly easier to understand.
for el in vec.iter() {
sum = el + sum; // now this works without changing the type of el
// you don't even need to dereference el anymore
// as Rust does it automatically.
}
sum as f32 / vec.len() as f32 // now you need to cast to f32 twice at the end
}
}

How to operate on 2 mutable slices of a Rust array?

I have a function that needs to operate on two parts of a single array.
The purpose is to be able to build an #[nostd] allocator that can return a variable slice of a bigger array to the caller and hang on to the remainder of the array for future allocations.
Here's example code that fails:
fn split<'a>(mut item: &'a mut [i32], place: usize) -> (&'a mut [i32], &'a mut [i32]) {
(&mut item[0..place], &mut item[place..])
}
fn main() {
let mut mem: [i32; 2048] = [1; 2048];
let (mut array0, mut array1) = split(&mut mem[..], 768);
array0[0] = 4;
println!("{:?} {:?}", array0[0], array1[0]);
}
the error is as follows:
error[E0499]: cannot borrow `*item` as mutable more than once at a time
--> src/main.rs:2:32
|
2 | (&mut item[0..place], &mut item[place..])
| ---- ^^^^ second mutable borrow occurs here
| |
| first mutable borrow occurs here
3 | }
| - first borrow ends here
This pattern also can be helpful for in-place quicksort, etc.
Is there anything unsafe about having two mutable references to nonoverlapping slices of the same array? If there's no way in pure Rust, is there a "safe" unsafe incantation that will allow it to proceed?
Is there anything unsafe about having two mutable references to nonoverlapping slices of the same array?
There isn't, but Rust's type system cannot currently detect that you're taking mutable references to two non-overlapping parts of a slice. As this is a common use case, Rust provides a safe function to do exactly what you want: std::slice::split_at_mut.
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])
Divides one &mut into two at an index.
The first will contain all indices from [0, mid) (excluding the index
mid itself) and the second will contain all indices from [mid, len)
(excluding the index len itself).
The final code is:
fn main() {
let mut mem : [i32; 2048] = [1; 2048];
let (mut array0, mut array1) = mem[..].split_at_mut(768);
array0[0] = 4;
println!("{:?} {:?}", array0[0], array1[0]);
}
Wow that was such a perfect match. Thanks for finding this!

How do I find the index of an element in an array, vector or slice?

I need to find an index of an element in a vector of strings. This is what I got so far:
fn main() {
let test: Vec<String> = vec![
"one".to_string(),
"two".to_string(),
"three".to_string(),
"four".to_string(),
];
let index: i32 = test
.iter()
.enumerate()
.find(|&r| r.1.to_string() == "two".to_string())
.unwrap()
.0;
}
It produces an error:
error[E0308]: mismatched types
--> src/main.rs:9:22
|
9 | let index: i32 = test
| ______________________^
10 | | .iter()
11 | | .enumerate()
12 | | .find(|&r| r.1.to_string() == "two".to_string())
13 | | .unwrap()
14 | | .0;
| |__________^ expected i32, found usize
I assume that's because enumerate() returns a tuple of (usize, _) (correct me if I'm wrong), but how do I convert usize to i32 here? If there is a better approach, I'm open to suggestions.
I think you should look at the position method instead.
fn main() {
let test = vec!["one", "two", "three"];
let index = test.iter().position(|&r| r == "two").unwrap();
println!("{}", index);
}
You can test it here.
Note that this works for any iterator, so it can be used for vectors, arrays, and slices, all of which produce iterators.
TLDR Use an iterator with the position method, the Rust docs shows a good example.
No, it's because indices are usize, not i32. In fact, i32 is completely inappropriate for this purpose; it may not be large enough, and there's no reason for it to be signed. Just use usize.
Some other notes: calling to_string() is not free, and you don't need it for the comparison; you can compare string slices just fine!
Also, if you really want to turn a usize into an i32, you can do that with a cast: x as i32, though this will not produce an error on over- or under-flow (i.e. the result may be negative).
All that said, as noted in Mathieu David's answer, there's a position method on iterators that does what you want.

Resources