Reputation: 1503
I am trying to convert a HashMap
to a String
where every item is separated by ,
and a key/value pair is represented using the format key:value
.
For example, a HashMap
HashMap::from([
(1, 5),
(2, 10),
(3, 20),
]);
should be converted to the String
3:20,2:10,1:5
My code below appears to work, I am only able to get it to work by using a strange way of concatenating the strings in the closure for map
. Also do not understand why the first element needed to use .to_owned()
while the last element uses .as_str()
.
.map(|(k, v)| String::from(k.to_string().to_owned() + ":" + v.to_string().as_str()) )
Is there a better way to write this?
use std::collections::HashMap;
fn main() {
let foo = HashMap::from([
(1, 5),
(2, 10),
(3, 20),
]);
let res = foo
.iter()
.map(|(k, v)| String::from(k.to_string().to_owned() + ":" + v.to_string().as_str()) )
.collect::<Vec<String>>()
.join(",");
println!("{}", res);
}
Upvotes: 0
Views: 865
Reputation: 1731
I would probably use format!
here:
use std::collections::HashMap;
fn main() {
let foo = HashMap::from([
(1, 5),
(2, 10),
(3, 20),
]);
let res = foo
.iter()
.map(|(k, v)| format!("{}:{}", k, v))
.collect::<Vec<String>>()
.join(",");
println!("{}", res);
}
If you really want to avoid unnecessary allocation for the Vec
and intermediate String
s (see also this question) you could adopt a slightly different approach and do this with a fold:
use std::collections::HashMap;
use std::fmt::Write;
fn main() {
let foo = HashMap::from([(1, 5), (2, 10), (3, 20)]);
let res = foo.iter().fold(String::new(), |mut s, (k, v)| {
if !s.is_empty() {
s.push(',');
}
write!(s, "{}:{}", k, v).expect("write! on a String cannot fail");
s
});
println!("{}", res);
}
Upvotes: 2