问题
If I want to take a &str
like "aeiou"
and turn it into an iterator roughly equivalent to ["a", "e", "i", "o", "u"].iter()
, what's the most idiomatic way to do it?
I've tried doing "aeiou".split("")
which seemed idiomatic to me, but I got empty &str
s at the beginning and end.
I've tried doing "aeiou".chars()
but it got pretty ugly and unwieldy from there trying to turn the char
s into &str
s.
For the time being, I just typed out ["a", "e", "i", "o", "u"].iter()
, but there's got to be an easier, more idiomatic way.
For context, I'm eventually going to be looping over each value and passing it into something like string.matches(vowel).count()
.
Here's my overall code. Maybe I went astray somewhere else.
fn string_list_item_count<'a, I>(string: &str, list: I) -> usize
where
I: IntoIterator<Item = &'a str>,
{
let mut num_instances = 0;
for item in list {
num_instances += string.matches(item).count();
}
num_instances
}
// snip
string_list_item_count(string, vec!["a", "e", "i", "o", "u"])
// snip
If I could make string_list_item_count
accept the std::str::pattern::Pattern
trait inside the iterator, I think that would make this function accept iterators of &str
and char
, but the Pattern
trait is a nightly unstable API and I'm trying to avoid using those.
回答1:
You can use split_terminator instead of split
to skip the empty string at the end of the iterator. Additionally, if you skip the first element of the iterator, you get the result you want:
let iterator = "aeiou".split_terminator("").skip(1);
println!("{:?}", iterator.collect::<Vec<_>>());
Output:
["a", "e", "i", "o", "u"]
回答2:
I would use str::split
with an empty string and then remove any empty strings using Iterator::filter
:
fn string_chars(s: &str) -> impl Iterator<Item = &str> {
s.split("").filter(|s| !s.is_empty())
}
fn main() {
assert_eq!(
string_chars("aeiou").collect::<Vec<_>>(),
["a", "e", "i", "o", "u"],
);
}
回答3:
A closure can also serve as a Pattern:
fn main() {
let vowels = "aeiou";
let s = "the quick brown fox jumps over the lazy dog";
let count = string_item_count(s, vowels);
dbg!(count);
}
fn string_item_count(string: &str, pat: &str) -> usize {
let pred = |c| pat.contains(c);
string.matches(pred).count()
}
来源:https://stackoverflow.com/questions/59597751/in-rust-whats-the-idiomatic-way-to-split-a-str-into-an-iterator-of-strs-of-o