Struct 如何将一个结构向量映射或转换为另一个结构向量? 最小可重复示例 pub结构用户{ 酒吧id:i32, 酒吧名称:String, pub match_id:i32, } 发布结构匹配{ 酒吧id:i32, 酒吧名称:String, } pub结构与用户匹配{ 酒吧id:i32, 酒吧名称:String, 酒吧用户:Vec, } fn main(){ 让我们查询结果:Vec=Vec[ ( 匹配{ id:1, 名称:String::from(“第一个匹配”), }, 一些(用户){ id:1, 名称:String::from(“Jack”), 匹配id:1, }), ), ( 匹配{ id:2, 名称:String::from(“第二个匹配”), }, 一些(用户){ id:2, 名称:String::from(“John”), 匹配id:2, }), ), ( 匹配{ id:3, 名称:String::from(“第三匹配”), }, 没有一个 ), ]; 让mut响应:Vec=Vec::new(); 对于(m,u)输入查询结果(&u){ 让现有的_匹配=&响应 .into_iter() .find(| match_with_user | match_with_user.id==m.id); 匹配现有的\u匹配{ 一些(找到匹配项)=>{ println!(“将用户插入匹配项:{}”,找到了\u match.name); 匹配你{ 一些(多用户)=>{ 找到匹配的.users.push(用户); } 无=>println!(“无用户”), } } 无=>{ println!(“没有现有匹配项。添加到响应。”); 让user=u.as_ref().unwrap(); 响应。推送(与用户匹配){ id:m.id, 名称:m.name.clone(), 用户:vec![], }); } } } println!(“带有:{}的响应,Response.len()); } 警告:未使用的变量:`user` -->src/main.rs:69:21 | 69 |让用户=u.作为|参考().展开(); ^ ^ ^ ^帮助:考虑前缀与下划线:“用户” | =注意:`#[警告(未使用的_变量)]`默认打开 警告:变量不需要是可变的 -->src/main.rs:61:26 | 61 |一些(多用户)=>{ | ----^^^^ | | |帮助:删除此“mut”` | =注意:`#[warn(unused_mut)]`默认打开 错误[E0382]:使用移动值:`response` -->src/main.rs:53:31 | 50 |让mut响应:Vec=Vec::new(); |-----发生移动是因为`response`的类型为`std::vec::vec`,而该类型未实现`Copy`特性 ... 53 |让现有的_匹配=&响应 |^^^^^^^^^值在循环的上一次迭代中移动到此处 错误[E0507]:无法移出共享引用后面的'u.0' -->src/main.rs:60:23 | 60 |匹配u{ | ^ 61 |一些(多用户)=>{ | -------- | | |数据移到这里 |发生移动是因为'user'的类型为'user',而该类型不实现'Copy'特性 错误[E0596]:无法将'found_match.users'作为可变项借用,因为它位于`&`引用后面 -->src/main.rs:62:25 | 62 |找到|匹配.用户.推送(用户); |^^^^^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
我的问题 我有 以下方法执行Diesel查询,并应将结果映射到JSON响应。这是数据库中所有匹配用户的响应。用户应嵌套在每个Struct 如何将一个结构向量映射或转换为另一个结构向量? 最小可重复示例 pub结构用户{ 酒吧id:i32, 酒吧名称:String, pub match_id:i32, } 发布结构匹配{ 酒吧id:i32, 酒吧名称:String, } pub结构与用户匹配{ 酒吧id:i32, 酒吧名称:String, 酒吧用户:Vec, } fn main(){ 让我们查询结果:Vec=Vec[ ( 匹配{ id:1, 名称:String::from(“第一个匹配”), }, 一些(用户){ id:1, 名称:String::from(“Jack”), 匹配id:1, }), ), ( 匹配{ id:2, 名称:String::from(“第二个匹配”), }, 一些(用户){ id:2, 名称:String::from(“John”), 匹配id:2, }), ), ( 匹配{ id:3, 名称:String::from(“第三匹配”), }, 没有一个 ), ]; 让mut响应:Vec=Vec::new(); 对于(m,u)输入查询结果(&u){ 让现有的_匹配=&响应 .into_iter() .find(| match_with_user | match_with_user.id==m.id); 匹配现有的\u匹配{ 一些(找到匹配项)=>{ println!(“将用户插入匹配项:{}”,找到了\u match.name); 匹配你{ 一些(多用户)=>{ 找到匹配的.users.push(用户); } 无=>println!(“无用户”), } } 无=>{ println!(“没有现有匹配项。添加到响应。”); 让user=u.as_ref().unwrap(); 响应。推送(与用户匹配){ id:m.id, 名称:m.name.clone(), 用户:vec![], }); } } } println!(“带有:{}的响应,Response.len()); } 警告:未使用的变量:`user` -->src/main.rs:69:21 | 69 |让用户=u.作为|参考().展开(); ^ ^ ^ ^帮助:考虑前缀与下划线:“用户” | =注意:`#[警告(未使用的_变量)]`默认打开 警告:变量不需要是可变的 -->src/main.rs:61:26 | 61 |一些(多用户)=>{ | ----^^^^ | | |帮助:删除此“mut”` | =注意:`#[warn(unused_mut)]`默认打开 错误[E0382]:使用移动值:`response` -->src/main.rs:53:31 | 50 |让mut响应:Vec=Vec::new(); |-----发生移动是因为`response`的类型为`std::vec::vec`,而该类型未实现`Copy`特性 ... 53 |让现有的_匹配=&响应 |^^^^^^^^^值在循环的上一次迭代中移动到此处 错误[E0507]:无法移出共享引用后面的'u.0' -->src/main.rs:60:23 | 60 |匹配u{ | ^ 61 |一些(多用户)=>{ | -------- | | |数据移到这里 |发生移动是因为'user'的类型为'user',而该类型不实现'Copy'特性 错误[E0596]:无法将'found_match.users'作为可变项借用,因为它位于`&`引用后面 -->src/main.rs:62:25 | 62 |找到|匹配.用户.推送(用户); |^^^^^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^,struct,rust,Struct,Rust,我的问题 我有 以下方法执行Diesel查询,并应将结果映射到JSON响应。这是数据库中所有匹配用户的响应。用户应嵌套在每个Match节点中 我的解决方案尝试 我创建一个向量 迭代查询结果 检查匹配是否已存在于my vector中,如果已存在,请添加用户信息(来自查询结果)并将其添加到当前MatchWithUser中的users属性中,否则只需向向量添加一个结构(MatchWithUsers) 如果从itertools板条箱中使用,并且确保查询结果按匹配ID排序,则可以非常轻松地获得与每个匹配相
Match
节点中
我的解决方案尝试
MatchWithUser
中的users属性中,否则只需向向量添加一个结构(MatchWithUsers
)如果从
itertools
板条箱中使用,并且确保查询结果按匹配ID排序,则可以非常轻松地获得与每个匹配相关联的用户的匹配列表:
use itertools::Itertools; // 0.9.0
let response: Vec<_> = query_result
.into_iter()
// Note that this assumes that `query_result` is sorted
// by match id since `group_by` only considers
// consecutive matches.
.group_by(|(m, _)| m.id)
.into_iter()
.map(|(id, mut g)| {
// Now `g` is an iterator of `(Match, Option<User>)`
// where all the matches are the same. We take the
// first item to get the match information. Note
// that it is safe to unwrap here because `group_by`
// would never call us with an empty `g`.
let (m, u) = g.next().unwrap();
MatchWithUsers {
id: id,
name: m.name,
// We got the first user along with the match
// information, now we append the other users
// from the remaining items in `g`.
users: u
.into_iter()
.chain(g.flat_map(|(_, u)| u.into_iter()))
.collect(),
}
})
.collect();
使用itertools::itertools;//0.9.0
let response:Vec=查询结果
.into_iter()
//请注意,这假定“查询结果”已排序
//按匹配id,因为“group_by”只考虑
//连续的比赛。
.group|by(|(m,|)m.id)
.into_iter()
.map(|(id,mut g)|{
//现在'g'是`(匹配,选项)的迭代器`
//所有的比赛都是一样的,我们拿
//获取匹配信息的第一项。注意
//在这里拆开是安全的,因为“分组”`
//永远不会用空的“g”称呼我们。
设(m,u)=g.next().unwrap();
与用户匹配{
id:id,
姓名:m.name,
//我们在比赛中得到了第一个用户
//信息,现在我们附加其他用户
//从“g”中的剩余项中。
用户:u
.into_iter()
.chain(g.flat_映射(|(|,u)| u.到_iter())
.collect(),
}
})
.收集();
而不是<代码> VEC<代码>,你应该考虑使用<代码> HashMap <代码>,这将在寻找重复的时候更有效,然后使用API来插入或修改存储的值。@ JMB感谢反馈和回答。我已经用错误文本更新了问题。我也会给HashMap一个尝试。我见过一些EX。我很喜欢,但我觉得有点不一样
use crate::schema::{matches, users};
use serde::{Deserialize, Serialize};
#[derive(Queryable, Identifiable, Associations, Serialize, Deserialize)]
#[belongs_to(Match)]
#[table_name = "users"]
pub struct User {
pub id: i32,
pub name: String,
pub match_id: i32,
}
#[derive(Queryable, Identifiable, Serialize, Deserialize)]
#[table_name = "matches"]
pub struct Match {
pub id: i32,
pub name: String,
pub players_count: i32,
}
#[derive(Serialize, Deserialize)]
pub struct MatchWithUsers {
pub id: i32,
pub name: String,
pub players_count: i32,
pub users: Vec<User>,
}
use itertools::Itertools; // 0.9.0
let response: Vec<_> = query_result
.into_iter()
// Note that this assumes that `query_result` is sorted
// by match id since `group_by` only considers
// consecutive matches.
.group_by(|(m, _)| m.id)
.into_iter()
.map(|(id, mut g)| {
// Now `g` is an iterator of `(Match, Option<User>)`
// where all the matches are the same. We take the
// first item to get the match information. Note
// that it is safe to unwrap here because `group_by`
// would never call us with an empty `g`.
let (m, u) = g.next().unwrap();
MatchWithUsers {
id: id,
name: m.name,
// We got the first user along with the match
// information, now we append the other users
// from the remaining items in `g`.
users: u
.into_iter()
.chain(g.flat_map(|(_, u)| u.into_iter()))
.collect(),
}
})
.collect();