Linq 如何在Powershell中将对象集合转换为另一种类型的新对象集合?

Linq 如何在Powershell中将对象集合转换为另一种类型的新对象集合?,linq,powershell,projection,Linq,Powershell,Projection,假设我有一个方法,该方法获取我的枚举类型ProjectName的枚举集合,并且有一个服务器对象集合,我希望在名为Project的类型中与这些ProjectName关联;如何在Powershell Select对象或LINQ的Select的其他等效对象中执行此操作 我想在Powershell中生成的C等价物是: var servers = new[] { new Server(/*someOtherProjectsCollection goes here*/), new Serve

假设我有一个方法,该方法获取我的枚举类型ProjectName的枚举集合,并且有一个服务器对象集合,我希望在名为Project的类型中与这些ProjectName关联;如何在Powershell Select对象或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时,它只是以字符串形式返回代码,我甚至无法将其强制转换到[Project[]。我认为问题可能在于对Select对象使用大括号,但我不确定如何在Select对象中创建新的项目对象。

您希望ForEach对象而不是Select对象为每个项目名称返回一个新的[Project]实例;此外,您的代码还可以简化:

$projects = GetProjectNames | ForEach-Object {
    $projectName = $_
    [Project]::new(
      $projectName, 
      $servers.Where({ $_.projects -eq $projectName })
    )
}
选择对象用于基于输入对象的选择属性创建新的自定义对象;相比之下,您正在从每个输入对象构造一个新的特定类型实例,这必须在ForEach对象调用中完成,在该调用中您可以显式地控制输出

$\ projects-eq$projectName作为条件依赖于PowerShell将-eq与数组一起用作LHS的能力,在这种情况下,将执行过滤,并返回过滤后的子数组;因为.Where将脚本块的输出解释为布尔值,所以空子数组被解释为$false,而至少有一个元素的子数组被解释为$true

还请注意,鉴于PowerShell的隐式输出行为,您不需要显式返回:因为新构造的[Project]实例没有分配给变量或发送到其他地方,所以它会自动返回


将Select对象替换为ForEach对象作为旁白:GetProjectNames应该是GetProjectNames,因为PowerShell cmdlet和函数的调用与shell命令类似,而与方法不同。也就是说,参数列表周围没有括号,参数之间用空格分隔,将数组构造为单个参数。太棒了!因此,对于Powershell的ForEach对象隐式返回行为,它是否会返回第一条语句,该语句返回某个内容而不将其赋值给任何内容,或者语句块中的最后一个或某些组合/元组???@MattArnold:如果所有语句都产生输出,并且该输出未被抑制、捕获或重定向,则它将返回所有语句的输出。虽然这很方便,但也构成了一个陷阱,因为很容易意外地产生输出。使用$null=。。。放弃不需要的输出。@MattArnold:P.S.:当一个cmdlet/function/script/script块产生多个输出时:如果通过管道将它们发送到另一个命令,它们将一个接一个地发送,并立即发送到所包含的cmdlet/function/。。。不必先跑完;如果在变量中捕获输出,它们将收集在[object[]]System.object[]数组中;如果只有一个输出对象,则会捕获它,因为没有创建数组。是否必须使用$null=。。。在前面的语句中,如果您在打算返回的实际语句中使用return,则返回值?@MattArnold:是。回报只是语法上的糖;return,即隐式输出语句,随后退出手头的代码单元。唯一的例外是使用class关键字创建的PSv5+自定义类,它们的方法与C中的工作方式相同:无隐式输出,强制使用return-请参阅