0

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);
}

1 Answer 1

2

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);
}

playground


If you really want to avoid unnecessary allocation for the Vec and intermediate Strings (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);
}

playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.