英文:
Iterate over vector and push to a hashmap vector value in rust?
问题
我有一个用户向量,我想将它转换成一个哈希映射,其中键是用户的级别(一个字符串),值是用户的向量。
#[derive(Debug, Serialize, Deserialize)]
pub struct User {
pub id: String,
pub email: String,
pub first_name: String,
pub last_name: String,
pub level: String,
}
let users: Vec<User> = serde_json::from_str(&data).unwrap();
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user);
}
但我得到了这个错误 mismatched types expected 'User', found '&User'
有人可以帮我解决这个问题吗?我是 Rust 新手。
英文:
I have this vector of users and i want to transform it into hashmap with key as level of user (which is a string) and value as a vector of users
#[derive(Debug, Serialize, Deserialize)]
pub struct User {
pub id: String,
pub email: String,
pub first_name: String,
pub last_name: String,
pub level: String,
}
let users: Vec<User> = serde_json::from_str(&data).unwrap();
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user);
}
But i'm getting this error mismatched types expected 'User', found '&User'
Can anyone help me with this? i'm new to rust
答案1
得分: 3
iter
生成一个引用迭代器。如果您保留了Vec
,这将非常有用,特别是因为您不需要克隆键。
let mut users_by_level: HashMap<&str, Vec<&User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(&user.level)
.or_insert(Vec::new())
.push(user);
}
如果您想将所有权转移到HashMap
,例如当您不需要Vec
或者想要更改项目时,可以使用into_iter
。
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.into_iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user);
}
for
循环会自动调用into_iter
,因此您可以直接传递users
以获得相同的效果。
for user in users {
英文:
iter
produces an iterator of references. This is useful if you keep the Vec
around, especially since you don't need to clone the key.
let mut users_by_level: HashMap<&str, Vec<&User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(&user.level)
.or_insert(Vec::new())
.push(user);
}
If you want to transfer ownership to the HashMap
, like when you don't need the Vec
or you want to mutate the items, you can use into_iter
.
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.into_iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user);
}
For loops call into_iter
automatically, so you can simply pass users
directly to get the same thing.
for user in users {
答案2
得分: 0
给你报错类型不匹配的原因是,当你遍历一个像 Vec 这样的集合时,你会得到一个对集合内部数据的引用。在这种情况下,由于你正在遍历用户向量,for 循环中的单个条目是类型为 User 的借用 &User
,因此在将其插入到 HashMap 中时,你应该尝试克隆正在迭代的用户,像这样:
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct User {
pub id: String,
pub email: String,
pub first_name: String,
pub last_name: String,
pub level: String,
}
fn main() {
let users: Vec<User> = serde_json::from_str(&data).unwrap();
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user.clone());
}
}
用户结构体可以派生克隆特质,因为它由可克隆的类型组成(在这种情况下是拥有的字符串)。然后在 for 循环中,当你将用户作为值插入时,你使用 .clone()
方法将用户复制到可变的 HashMap 中。
英文:
The reason why its giving you a mismatch type error is that when you are iteration through a collection like a Vec, you are given a borrow to the data within the collection. In this case since you are iterating through the users vector, the individual entry within the for loop is a borrow of type User &User
, therefore you should attempt to clone the user that is being iterated when you insert it within the HashHap, like so:
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct User {
pub id: String,
pub email: String,
pub first_name: String,
pub last_name: String,
pub level: String,
}
fn main() {
let users: Vec<User> = serde_json::from_str(&data).unwrap();
let mut users_by_level: HashMap<String, Vec<User>> = HashMap::new();
for user in users.iter() {
users_by_level
.entry(user.level.clone())
.or_insert(Vec::new())
.push(user.clone());
}
}
The user struct can derive the clone trait since it is made up of types that can be cloned (in this case owned Strings). Then in the for loop when you insert user as the value, you use the .clone()
method to copy the user to mutable HashMap.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论