'HashMap with key referring a field in the value [duplicate]
I want to create a hash map from a vector of entities. I want the key to be a reference to a field in the corresponding value. This is something I have come up with.
struct Entity {
id: String,
patterns: Vec<Pattern>,
}
struct Package<'ent> {
entity_map: HashMap<&'ent String, Entity>,
}
impl<'ent> Package<'ent> {
fn from(entities: Vec<Entity>) -> Self {
let entity_map: HashMap<&String, Entity> =
entities.into_iter().map(|e| (&e.id, e)).collect();
Package { entity_map }
}
}
Of course, this isn't working. I am pretty new to Rust. Is there anything wrong with this approach? How can I achieve what I want? Any help will be appreciated.
Solution 1:[1]
In this case I think your best bet is to have the HashMap's keys and values both be references to elements in the original Vec, which should itself be passed by reference (as a slice, the more general version of &Vec) instead of by value.
use std::collections::HashMap;
struct Pattern;
struct Entity {
id: String,
patterns: Vec<Pattern>,
}
struct Package<'ent> {
// Now the values are references too
entity_map: HashMap<&'ent String, &'ent Entity>,
}
impl<'ent> Package<'ent> {
// Package<'ent> can be constructed from any slice that outlives it
fn from(entities: &'ent [Entity]) -> Self {
let entity_map = entities
.iter()
.map(|e| (&e.id, e))
.collect::<HashMap<_, _>>();
Package { entity_map }
}
}
As an aside, if you're implementing the function from(T), you probably want to do so as part of the implementation of the trait From<T> for your type.
If you can't store the vector for long enough to make the above solution work, then you can simply split Entity into its key and value components, which can then be used as owned values in the HashMap.
// Same Pattern and Entity as above
struct EntityValue {
patterns: Vec<Pattern>,
}
impl Package {
fn from(entities: Vec<Entity>) -> Self {
let entity_map = entities
.into_iter()
.map(|e| {
let Entity { id, patterns } = e;
(id, EntityValue { patterns })
})
.collect::<HashMap<_, _>>();
Package { entity_map }
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
