#[derive(Debug, PartialEq)]
pub enum Comparison {
Equal,
Sublist,
Superlist,
Unequal,
}
pub fn sublist<T: PartialEq>(_first_list: &[T], _second_list: &[T]) -> Comparison {
let _first_list_string = _first_list.join(" ");
println!("{}", _first_list_string);
}
#[test]
#[ignore]
fn huge_sublist_not_in_huge_list_2() {
let v1: Vec = vec![0; 1_000_000];
let mut v2: Vec = vec![0; 500_000];
v2.push(1);
assert_eq!(Comparison::Unequal, sublist(&v1, &v2));
}
I want to convert the &[T] into a big string using .join method but I am getting these issues.
the method join
exists for reference &[T]
, but its trait bounds were not satisfied
method cannot be called on &[T]
due to unsatisfied trait bounds
note: the following trait bounds were not satisfied:
[T]: std::slice::Join<_>
rustc(E0599)
main.rs(157, 42): method cannot be called on &[T]
due to unsatisfied trait bounds
the method join
exists for reference &[T]
, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
[T]: Join<_>
rustcE0599
I am new to rust and not able to figure out what is going wrong... Can anyone please help me to convert the slice into string?
What are you expecting to get from _first_list.join(" ")
? The only thing you know about T
is that you can compare it with itself, but join
will have to somehow build a string - how?
2 Likes
For instance i need output of vec![0; 1_000_000]; as "0 1 2 .... 1_000_000" but i am not able to figure out how to do it.
If you want to be able to print for any arbitrary T
, it must have a trait bound which allows it to be convertible to a string. Two common such traits are Debug
and Display
. For numbers, you can use either - in general if you want to print something Display
makes more sense, while Debug
is as the name suggests more for debug output.
So, in your case, you need a trait bound of T: PartialEq + Display
. Then you can do something like:
let first_list_str = first_list.into_iter().cloned().map(Display::to_string).collect::<Vec<_>>();
let first = first_list_str.join(" ");
println!("{}", first);
2 Likes
This will not work - one must either collect
to the intermediate vector first, or use something like Itertools::join
.
Thanks for the help I guess I understood that I need format the type and use it
#[derive(Debug, PartialEq)]
pub enum Comparison {
Equal,
Sublist,
Superlist,
Unequal,
}
pub fn rem_first_and_last(value: &str) -> &str {
let mut chars = value.chars();
chars.next();
chars.next_back();
chars.as_str()
}
pub fn form_string<T: std::fmt::Debug> (_first_list: &[T], _second_list: &[T]) -> bool {
let mut _first_list_string = format!("{:?}",_first_list);
let mut _second_list_string = format!("{:?}", _second_list);
_first_list_string = rem_first_and_last(_first_list_string.as_str()).to_string();
_second_list_string = rem_first_and_last(_second_list_string.as_str()).to_string();
return _second_list_string.contains(_first_list_string.as_str())
}
pub fn check_equal<T: std::fmt::Debug> (_first_list: &[T], _second_list: &[T]) -> bool {
let mut _first_list_string = format!("{:?}",_first_list);
let mut _second_list_string = format!("{:?}", _second_list);
_first_list_string = rem_first_and_last(_first_list_string.as_str()).to_string();
_second_list_string = rem_first_and_last(_second_list_string.as_str()).to_string();
return _second_list_string == _first_list_string.as_str()
}
pub fn sublist<T: std::fmt::Debug>(_first_list: &[T], _second_list: &[T]) -> Comparison {
if check_equal(_first_list, _second_list) {
return Comparison::Equal
} else if _first_list.len() < _second_list.len() && form_string(_first_list, _second_list) {
Comparison::Sublist
} else if _first_list.len() > _second_list.len() && form_string(_second_list, _first_list) {
Comparison::Superlist
} else {
Comparison::Unequal
}
}
This solved everything I need and I passed all the test cases thanks for the help!
You can check my question and solution on this Exercism