如何在 Powershell 中将对象集合转换为另一种类型的新对象集合?
How does one Transform a Collection of Objects into a Collection of new Objects of another Type in Powershell?
假设我有一个方法可以获取我的枚举类型 ProjectName
的枚举集合,并且有一个 Server
对象的集合,我想将这些 ProjectName
关联到一个叫做 Project
的类型;我如何在 Powershell Select-Object
(或 LINQ 的 Select
的其他等效项)中执行此操作。
我想在 Powershell 中生成的 C# 等价物是这样的:
var servers = new[]
{
new Server(/*someOtherProjectsCollection goes here*/),
new Server(/*someOtherProjectsCollection goes here*/),
new Server(/*someOtherProjectsCollection goes here*/)
};
var projects = GetProjectNames().Select(projectName => new Project(projectName, servers.Where(server => server.Projects.Any(serverProject => serverProject.Name == projectName))));
但是我有的是:
$servers = [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/)
$projects = (GetProjectNames()) | Select-Object {
$selectedProjectName = $_
return [Project]::new($_, ($servers | Where-Object { $_.projects.Where({ $_ -eq $selectedProjectName }).Count -gt 0 }))
}
当我尝试在 Powershell LSE 中读取 $projects
时(在最后一行之后的断点上),它只是 returns 代码作为字符串,我什至无法转换它至 [Project[]]
。我认为问题可能出在 Select-Object
中使用大括号,但我不确定如何在 Select-Object
.
中创建新的 Project
对象
您希望 ForEach-Object
而不是 Select-Object
到 return 每个项目名称的新 [Project]
实例;另外,您的代码可以精简:
$projects = GetProjectNames | ForEach-Object {
$projectName = $_
[Project]::new(
$projectName,
$servers.Where({ $_.projects -eq $projectName })
)
}
Select-Object
用于根据输入对象的 select 属性创建新的自定义对象;相比之下,您正在从每个输入对象构造一个新的特定类型实例,这必须在 ForEach-Object
调用中完成,您可以在其中明确控制输出。
$_.projects -eq $projectName
作为条件依赖于 PowerShell 使用 -eq
和 array 作为 LHS 的能力,在这种情况下 过滤,过滤后的子数组被return编辑;因为 .Where()
将脚本块的输出解释为 布尔值 ,空子数组被解释为 $false
,而具有至少一个元素的子数组被解释为 $true
.
另请注意,考虑到 PowerShell 的 隐式输出 行为,您不需要显式 return
:因为新构造的 [Project]
实例未分配给变量或发送到其他地方,它会自动 returned.
假设我有一个方法可以获取我的枚举类型 ProjectName
的枚举集合,并且有一个 Server
对象的集合,我想将这些 ProjectName
关联到一个叫做 Project
的类型;我如何在 Powershell Select-Object
(或 LINQ 的 Select
的其他等效项)中执行此操作。
我想在 Powershell 中生成的 C# 等价物是这样的:
var servers = new[]
{
new Server(/*someOtherProjectsCollection goes here*/),
new Server(/*someOtherProjectsCollection goes here*/),
new Server(/*someOtherProjectsCollection goes here*/)
};
var projects = GetProjectNames().Select(projectName => new Project(projectName, servers.Where(server => server.Projects.Any(serverProject => serverProject.Name == projectName))));
但是我有的是:
$servers = [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/)
$projects = (GetProjectNames()) | Select-Object {
$selectedProjectName = $_
return [Project]::new($_, ($servers | Where-Object { $_.projects.Where({ $_ -eq $selectedProjectName }).Count -gt 0 }))
}
当我尝试在 Powershell LSE 中读取 $projects
时(在最后一行之后的断点上),它只是 returns 代码作为字符串,我什至无法转换它至 [Project[]]
。我认为问题可能出在 Select-Object
中使用大括号,但我不确定如何在 Select-Object
.
Project
对象
您希望 ForEach-Object
而不是 Select-Object
到 return 每个项目名称的新 [Project]
实例;另外,您的代码可以精简:
$projects = GetProjectNames | ForEach-Object {
$projectName = $_
[Project]::new(
$projectName,
$servers.Where({ $_.projects -eq $projectName })
)
}
Select-Object
用于根据输入对象的 select 属性创建新的自定义对象;相比之下,您正在从每个输入对象构造一个新的特定类型实例,这必须在ForEach-Object
调用中完成,您可以在其中明确控制输出。$_.projects -eq $projectName
作为条件依赖于 PowerShell 使用-eq
和 array 作为 LHS 的能力,在这种情况下 过滤,过滤后的子数组被return编辑;因为.Where()
将脚本块的输出解释为 布尔值 ,空子数组被解释为$false
,而具有至少一个元素的子数组被解释为$true
.另请注意,考虑到 PowerShell 的 隐式输出 行为,您不需要显式
return
:因为新构造的[Project]
实例未分配给变量或发送到其他地方,它会自动 returned.