首页 > 解决方案 > 我想用员工导入 csv 并创建数据层次结构

问题描述

我正在尝试创建一个 powershell 脚本,该脚本将导入具有以下格式的员工的 csv。

ID,FirstName, LastName, Managers ID
1, John, Doe, 0 (is the top of hierarchy)
2, Jane, Doe, 1
45, Josh, Davis, 1
33, Steve, Clark, 2

我的问题是,由于员工在 csv 中,所以他们没有按层次结构的顺序排列。有没有办法组织这些人并将其导出到另一个 csv 文件?

标签: powershell

解决方案


正如@Kory Gill 已经提到的那样,您缺少一些正确定义请求的约束(并且它们也没有从您的示例中显示),例如:

  • IdManagerId不必按顺序排列
    (或者层次结构中更高的经理总是排在第一位?)
  • ManagerId和层级之间没有关系
    (或者层级中较高的经理总是较低的ManagerId?)
  • 层次结构的深度是未定义的(无限的)
    (我假设经理级别的数量在重组后总是会增加)

假设上述约束适用,问题会变得更复杂,但也更具挑战性。为了说明这一点,我Id将最高管理者的设置John Doe11并对列表进行了相应的排序,保持原始层次结构不变:

$Employees = ConvertFrom-Csv 'ID, FirstName, LastName, ManagerId
2, Jane, Doe, 11
11, John, Doe, 0 
45, Josh, Davis, 11
33, Steve, Clark, 2'

对于这个要求,您可能想要创建一个递归函数来找出经理的经理(经理......等)。下面是一个例子,你可以如何解决这个问题:

Function Add-ManagerLevel([Object[]]$Employees) {

    Function Get-Level($ManagerId, [Int]$Level = 0) {               # 0 is the top of hierarchy
        $Manager = $Employees | Where-Object {$_.Id -eq $ManagerId}
        If (!$Manager) {$Level} Else {Get-Level $Manager.ManagerId ($Level + 1)}
    }

    $Employees | ForEach-Object {
        $_ | Add-Member "Level" (Get-Level $_.ManagerId) -PassThru
    }
}

请注意,Get-Level帮助函数会调用自身来确定经理是否有更高的经理。
这将给出以下输出:

Add-ManagerLevel $Employees | Format-Table

ID FirstName LastName ManagerId Level
-- --------- -------- --------- -----
2  Jane      Doe      11            1
11 John      Doe      0             0
45 Josh      Davis    11            1
33 Steve     Clark    2             2

您可以在层次结构级别对列表进行排序,例如:

Add-ManagerLevel $Employees | Sort-Object Level | Format-Table

推荐阅读