How to convert a Vec<Duration> to Vec<(&str, u64)>?

Hello.
How to convert a Vec<Duration> to Vec<(&str, u64)>?

Please help.

    let _v: Vec<(&str, u64)> = m.freq_map().iter().map(|(i,v)|
    {
        let x = &i.as_millis().to_string() as &str;
        let z = v.clone();
        (x, z)
    }).collect();

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1b7cbbc2e3efcfd866125d6279b25bc4

The correct type for it is Vec<(String, u64)> or Vec<(Box<str>, u64>).

&str means "this is not a string, it has no data, I'm giving you a temporary permission to see a String I'm keeping elsewhere". But you're not keeping the String anywhere, you throw it away immediately. &str can't exist by itself.

.map(|(duration, value)| (duration.to_string(), *value))
2 Likes

My goal is to pass data to tui's function :
https://docs.rs/tui/0.1.3/tui/widgets/struct.BarChart.html#method.data

So you will need a two-step process. First make pairs of (String, u64) and then, while a vec of them is holding them and keeping them alive, make another vec that temporarily borrows them.

let owned_strings: Vec<(String, u64)> = …;
let borrowed_strings: Vec<(&str, u64)> = owned_strings.iter().map(|(s, v)| (s.as_str(), *v)).collect();

This is because Rust needs to free every string you created, but without a garbage collector Rust has no way of tracking how many strings exist and which are still needed. Holding them in a Vec makes it possible to track them and free them when they're not needed any more.

1 Like
let owned_strings: Vec<(String, u64)> = m.freq_map().iter().map(|(d,c)|{(d.as_millis().to_string(),*c)}).collect();
let _v: Vec<(&str, u64)> = owned_strings.iter().map(|(t,c)|{(t.as_str(), *c)}).collect();

@kornel ?

Yes, that should work.