首页 > 解决方案 > Powershell 过滤项目中项目的内在索引(例如使用 Where-Object)

问题描述

有什么方法可以 从 Where-Object 处理
中获取选定/过滤/匹配对象的内在数字索引 (order#)?

例如:

Get-Process | Where-Object -property id -eq 1024

不使用进一步的代码...
?是否可以
从某些“内部/隐藏”Powershell 机制中获取 ID=4 的对象的索引?

或指示 Where-Object 吐出
匹配发生的索引?
(在这种情况下为 1,0 是“空闲”进程)

标签: powershell

解决方案


不,从 PowerShell 7.1开始,您正在寻找的内容没有内置机制

如果只匹配一项- 如您的情况 - 您可以使用Array类型的静态.FindIndex()方法

$processes = Get-Process

# Find the 0-based index of the process with ID 1024.
[Array]::FindIndex($processes, [Predicate[object]] { param($o) $o.Id -eq 1024 })

请注意,如果找到匹配项,则返回从零开始的索引-1,否则返回。

::FindIndex() 方法的优点是只搜索第一个匹配项,不像Where-ObjectPowerShell 7.1 始终搜索整个输入集合(见下文)。作为一种方法而不是基于管道的cmdlet,它总是要求输入数组完全位于内存中(管道不需要)。

虽然它不会直接解决您的用例,但请注意在 GitHub 上有概念上相关的功能请求 #13772,它建议引入一个自动$PSIndex变量以在脚本块内部ForEach-Object提供。Where-Object


作为旁白:

请注意,虽然[Array]::FindIndex只能找到第一个匹配项的索引,Where-Object但以相反的方式受到限制:从 PowerShell 7.1 开始,它始终会找到所有匹配项,如果您只查找一个匹配项,则效率低下。

虽然相关的.Where()数组方法 确实提供了一种在第一次匹配后停止处理的方法(例如,
('long', 'foo', 'bar').Where({ $_.Length -eq 3 }, 'First')),但方法仅在内存中的集合上运行,因此如果基于管道的cmdlet也支持这样的功能会很有帮助 Where-Object - 请参阅GitHub功能请求 #13834



推荐阅读