i need split String "fooo:3333#baaar:22222" Firstly by # secondary by :
and result must be <Vec<Vec<&str, i64>>>
for the first step (split by #) i came up with
.split('#').collect::<Vec<&str>>()
but I can't think of a solution for the second step
CodePudding user response:
A Vec<&str, i64>
is not a thing, so I assume u meant (&str, i64)
You can create that by splitting first, then mapping over the chunks.
let v = s
.split('#') // split first time
// "map" over the chunks and only take those where
// the conversion to i64 worked
.filter_map(|c| {
// split once returns an `Option<(&str, &str)>`
c.split_once(':')
// so we use `and_then` and return another `Option`
// when the conversion worked (`.ok()` converts the `Result` to an `Option`)
.and_then(|(l, r)| r.parse().ok().map(|r| (l, r)))
})
.collect::<Vec<(&str, i64)>>();
References:
https://doc.rust-lang.org/std/primitive.str.html#method.split
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map
https://doc.rust-lang.org/core/primitive.str.html#method.split_once
https://doc.rust-lang.org/core/option/enum.Option.html#method.and_then
https://doc.rust-lang.org/std/primitive.str.html#method.parse
https://doc.rust-lang.org/std/result/enum.Result.html#method.ok
CodePudding user response:
You can call a closure on each element of an iterator returned by the first split and split inside closure and push values to the vector.
let mut out = Vec::new();
s.split('#').for_each(|x| out.push(x.split(":").collect::<Vec<&str>>()));