I am learning Rust and discovered this problem:
I would like to split a string by a pattern and remove all cases where the resultin substring is empty.
Here is an example:
let s = "s,o,m,e,";
for elem in s.split(",").skip_while(|&x| x.is_empty()) {
print!(" <{}> ", elem);
//print!(" <{}>({}) ", elem, elem.is_empty());
}
But the result is the following:
<s> <o> <m> <e> <>
My thoughts were: The struct Split
returned by split
implements Iterator
which provides skip_while
. IntelliSense told me the x
in the closure is of type &&str
so I would assume all the elements of the iterator (of type &str
) which are empty to be omitted.
But it doesn't skip the empty substring.
I also tried to print the result of the is_empty
function. It shows that the last slice is indeed empty. If I instead for the skip_while use skip_while(|&x| x == "s")
, it correctly leaves out the "s"
(printed with is_empty
here):
<o>(false) <m>(false) <e>(false) <>(true)
So somehow the slice behaves differently in the iterator?
Why is that or where am I mistaken?
If you only need to omit the 1 empty string at the end of input, just use split_terminator
instead of split
. This adapter is basically just like split
but it treats the pattern argument as a terminator instead of a separator, so the empty string at the end of input is not considered a new element.
If you truly want to skip all the empty strings, keep reading.
skip_while
is doing exactly as its documentation says (emphasis mine):
skip_while()
takes a closure as an argument. It will call this closure on each element of the iterator, and ignore elements until it returnsfalse
.After
false
is returned,skip_while()
's job is over, and the rest of the elements are yielded.
Filtering out all the elements that match a predicate, regardless of where they are in the sequence, is the job of filter
:
let s = ",s,o,,m,e,";
for elem in s.split(",").filter(|&x| !x.is_empty()) {
print!(" <{}> ", elem);
}
The above code will have the effect you wanted.
Note that the predicate to filter
has the opposite meaning to skip_while
: instead of returning true
for elements that should not be yielded, it returns true
for elements that should be yielded.
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