You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中对结构体向量使用group_by实现用户角色数据聚合

实现方案

Rust 标准库迭代器自带的group_by仅对相邻且相同分组键的元素生效,如果你不能保证输入数据已经按user_id排序,更推荐用HashMap实现全局分组:

方案1:HashMap实现(推荐,无排序要求、性能更高)

该方案直接转移元素所有权,无额外字符串拷贝开销:

use std::collections::HashMap;

#[derive(Debug)]
struct Temp {
    user_id: i32,
    username: String,
    role_id: i32,
    role: String,
}

#[derive(Debug)]
struct User {
    id: i32,
    username: String,
    roles: Vec<Role>,
}

#[derive(Debug)]
struct Role {
    id: i32,
    role: String,
}

fn main() {
    let temps_data = vec![
        Temp {
            user_id: 1,
            username: "test".to_string(),
            role_id: 1,
            role: "test1".to_string(),
        },
        Temp {
            user_id: 1,
            username: "test".to_string(),
            role_id: 2,
            role: "test2".to_string(),
        },
        Temp {
            user_id: 2,
            username: "demo".to_string(),
            role_id: 3,
            role: "test3".to_string(),
        },
    ];

    let mut groups: HashMap<i32, (String, Vec<Role>)> = HashMap::new();
    for temp in temps_data {
        // 按user_id分组,不存在则初始化用户信息和空角色列表
        let entry = groups.entry(temp.user_id).or_insert((temp.username, Vec::new()));
        // 向当前用户的角色列表追加角色
        entry.1.push(Role {
            id: temp.role_id,
            role: temp.role,
        });
    }

    // 将HashMap转换为目标User向量格式
    let result: Vec<User> = groups.into_iter()
        .map(|(user_id, (username, roles))| User {
            id: user_id,
            username,
            roles,
        })
        .collect();

    // 打印验证结果
    println!("{:#?}", result);
}

方案2:标准库group_by实现(需提前排序)

如果确定要用迭代器的group_by方法,必须先对输入数据按user_id排序,否则同一个用户的非相邻数据会被拆分为多个分组:

// 先按user_id对源数据排序
let mut sorted_temps = temps_data;
sorted_temps.sort_by_key(|temp| temp.user_id);

let result: Vec<User> = sorted_temps
    // 相邻元素user_id相同则分为一组
    .group_by(|a, b| a.user_id == b.user_id)
    .map(|group| {
        let first_item = group.first().unwrap();
        // 遍历组内所有元素生成角色列表
        let roles = group.iter()
            .map(|temp| Role {
                id: temp.role_id,
                role: temp.role.clone(),
            })
            .collect();
        User {
            id: first_item.user_id,
            username: first_item.username.clone(),
            roles,
        }
    })
    .collect();

内容的提问来源于stack exchange,提问作者igor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:18:02