C# Linq "join" 在 Rust 中的等价物是什么?

What is C# Linq "join" equivalent in rust?

我正在尝试在 Rust 中对两个向量执行内部连接,但不确定如何实现。
简而言之,我正在寻找具有部门名称的员工。

如果这里有人熟悉 C# LINQ,那么我将尝试在 Rust 中实现如下所示的功能。
考虑以下 model.rs

中指定的相同模型
from e in employees
join d in department
on e.dept_id equals d.dept_id
select new 
{
    DeptName= d.dept_name,
    Name = e.name
};

这是我的 Rust 语言代码:

models.rs

use bigdecimal::BigDecimal;
use chrono::{NaiveDateTime, Utc};

pub struct Department {
    pub dept_id: i32,
    pub dept_name: Option<String>,
    pub created_on: Option<NaiveDateTime>,
    pub created_by: Option<String>,
    pub modified_on: Option<NaiveDateTime>,
    pub modified_by: Option<String>,
    pub is_active: Option<bool>,
}

impl Department {
    pub fn get_departments() -> Vec<Department> {
        vec![
            Department {
                dept_id: 101,
                dept_name: Option::from("Software".to_string()),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Jadon".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
            Department {
                dept_id: 102,
                dept_name: Option::from("Hr".to_string()),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Jadon".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
            Department {
                dept_id: 103,
                dept_name: Option::from("Hr".to_string()),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Jadon".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
        ]
    }
}

pub struct Employee {
    pub employee_id: i32,
    pub name: Option<String>,
    pub age: Option<i32>,
    pub address: Option<String>,
    pub email: Option<String>,
    pub dept_id: i32,
    pub salary: Option<BigDecimal>,
    pub created_on: Option<NaiveDateTime>,
    pub created_by: Option<String>,
    pub modified_on: Option<NaiveDateTime>,
    pub modified_by: Option<String>,
    pub is_active: Option<bool>,
}

impl Employee {
    pub fn get_employees() -> Vec<Employee> {
        vec![
            Employee {
                employee_id: 1001,
                name: Option::from("Marten Babel".to_string()),
                age: Option::from(25),
                address: Option::from("Netherland".to_string()),
                email: Option::from("somemail@gmail.com".to_string()),
                dept_id: 101,
                salary: Option::from(BigDecimal::from(50000.00)),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Tom".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
            Employee {
                employee_id: 1002,
                name: Option::from("Jack Sancho".to_string()),
                age: Option::from(22),
                address: Option::from("England".to_string()),
                email: Option::from("jacksemail@gmail.com".to_string()),
                dept_id: 102,
                salary: Option::from(BigDecimal::from(80000.00)),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Tom".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
            Employee {
                employee_id: 1003,
                name: Option::from("Phil Foden".to_string()),
                age: Option::from(29),
                address: Option::from("England".to_string()),
                email: Option::from("philsemail@gmail.com".to_string()),
                dept_id: 101,
                salary: Option::from(BigDecimal::from(80000.00)),
                created_on: Option::from(Utc::now().naive_utc()),
                created_by: Option::from("Tom".to_string()),
                modified_on: None,
                modified_by: None,
                is_active: Option::from(true),
            },
        ]
    }
}

main.rs

fn main() {
    let department: Vec<Department> = Department::get_departments();
    for dept in department {
        println!(
            "Dept Id: {} and Dept Name: {}",
            dept.dept_id,
            dept.dept_name.unwrap_or_default()
        );
    }

    let employee: Vec<Employee> = Employee::get_employees();
    for emp in employee {
        println!(
            "Name is: {} and age is : {}",
            emp.name.unwrap_or_default(),
            emp.age.unwrap_or_default()
        )
    }
}

此处“dept_id”将充当外键。
main.rs 中的代码运行良好。我得到了部门和员工,但我怎样才能对这两个向量执行连接。

注意:到目前为止我还没有使用柴油机。只希望对这些向量执行连接。
有可能生锈吗?
谢谢

如果您只想获得成对的 &str 作为部门名称和员工名称,您可以使用像这样的迭代器链:

let department: Vec<Department> = Department::get_departments();
let employee: Vec<Employee> = Employee::get_employees();

let dept_employee_names = department.iter().flat_map(|d| {
    let dept_id = d.dept_id;
    let dept_name = &d.dept_name;
    employee
        .iter()
        .filter(move |e| e.dept_id == dept_id)
        .map(move |e| {
            (
                dept_name.as_deref().unwrap_or_default(),
                e.name.as_deref().unwrap_or_default(),
            )
        })
});

for (dept, emp) in dept_employee_names {
    println!("dept = {}, emp = {}", dept, emp);
}

请注意,这必须搜索每个部门的所有员工,但这确实是使用向量的限制。您可能可以通过更改数据结构来提高效率。