Is there a more elegant (or idiomatic) way to convert a vec into a map? The usual way i can think of is below:
use std::collections::BTreeMap;
#[derive(Debug, Clone)]
struct Data {
pub key: String,
pub val: u32,
}
impl Data {
pub fn new(key: &str, val: u32) -> Self { Self {key: key.to_string(), val} }
}
fn main() {
let my_vec = vec![ Data::new("A", 1),Data::new("B", 2),Data::new("C", 3) ];
let mut my_map = BTreeMap::new();
for d in my_vec {
my_map.insert(d.key.clone(), d); // storing the whole Data as value
}
println!("my_map: {:?}", my_map);
}
Note that, since you're consuming the Vec, I don't believe you need to Clone the key value. BTreeMap implements FromIterator for the tuple (K,V), so you can use the collect method:
let my_map: BTreeMap<_, _> = my_vec.into_iter().map(|data| (data.key, data.val)).collect();
4 Likes
Why not use iterator adaptors:
use std::collections::BTreeMap;
#[derive(Debug, Clone)]
struct Data {
pub key: String,
pub val: u32,
}
impl Data {
pub fn new(key: &str, val: u32) -> Self { Self {key: key.to_string(), val} }
}
fn main() {
let my_vec = vec![ Data::new("A", 1),Data::new("B", 2),Data::new("C", 3) ];
let my_map = my_vec
.into_iter()
.map(|x| (x.key.clone(), x))
.collect::<BTreeMap<_, _>>();
println!("my_map: {:?}", my_map);
}
1 Like
trentj
September 22, 2021, 2:55am
4
If Data
should exist and acts like a key-value pair, tell BTreeMap
about it:
impl FromIterator<Data> for BTreeMap<String, u32> {
fn from_iter<I>(xs: I) -> Self
where
I: IntoIterator<Item = Data>,
{
xs.into_iter().map(|Data { key, val }| (key, val)).collect()
}
}
Then simply :
let my_map = BTreeMap::from_iter(my_vec);
If Data
doesn't need to exist, just use tuples, which already work this way.
4 Likes
system
Closed
December 21, 2021, 6:56am
6
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.