Syl*_*rdy 115 arrays powershell member-enumeration
假设我们有一个对象数组$ objects.假设这些对象具有"名称"属性.
这就是我想要做的
$results = @()
$objects | %{ $results += $_.Name }
Run Code Online (Sandbox Code Playgroud)
这有效,但可以更好的方式完成吗?
如果我这样做:
$results = objects | select Name
Run Code Online (Sandbox Code Playgroud)
$results
是具有Name属性的对象数组.我希望$ results包含一个Name数组.
有没有更好的办法?
Sco*_*aad 196
我想你可以使用ExpandProperty
参数Select-Object
.
例如,要获取当前目录的列表并显示Name属性,可以执行以下操作:
ls | select -Property Name
Run Code Online (Sandbox Code Playgroud)
这仍然是返回DirectoryInfo或FileInfo对象.您可以通过管道到Get-Member(别名gm
)来检查通过管道传输的类型.
ls | select -Property Name | gm
Run Code Online (Sandbox Code Playgroud)
因此,要将对象扩展为您正在查看的属性类型,您可以执行以下操作:
ls | select -ExpandProperty Name
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您可以执行以下操作使变量成为字符串数组,其中字符串是Name属性:
$objects = ls | select -ExpandProperty Name
Run Code Online (Sandbox Code Playgroud)
rag*_*dqq 64
作为一个更简单的解决方案,您可以使用:
$results = $objects.Name
Run Code Online (Sandbox Code Playgroud)
哪个应该填充$results
元素中所有'Name'属性值的数组$objects
.
mkl*_*nt0 22
在何时使用哪种方法和性能比较的指导下,补充已有的,有用的答案.
在管道之外,使用:
__PRE__(PSv3 +),如rageandqq的回答所示,它在语法上更简单,更快.
在必须进一步处理结果或结果不适合整个内存的管道中,使用:
__PRE__
-ExpandProperty
解释了需要.对于小型输入集合(数组),您可能不会注意到差异,特别是在命令行上,有时能够轻松地键入命令更为重要.
这是一种易于使用的替代方案,但这是最慢的方法 ; 它使用称为操作语句的简化ForEach-Object
语法(同样,PSv3 +):; 例如,以下PSv3 +解决方案很容易附加到现有命令:
$results = foreach ($obj in $objects) { $obj.Name }
为了完整起见:鲜为人知的PSv4 + .ForEach()
收集方法是另一种选择:
$objects | Select-Object -ExpandProperty Name
这种方法类似于成员枚举,具有相同的权衡,除了不应用管道逻辑; 它稍微慢一些,但仍比管道快得多.
为了通过名称(字符串参数)提取单个属性值,此解决方案与成员枚举相同(尽管后者在语法上更简单).
的脚本块的变体,尽管慢得多,允许任意变换 ; 它是一种更快 - 一次性内存 - 替代基于管道的ForEach-Object
cmdlet.
以下是基于输入对象集合的各种方法的样本计时,平均为100次运行; 绝对数字并不重要,并且根据许多因素而有所不同,但它应该让您了解相对表现:%
$objects | % Name # short for: $objects | ForEach-Object -Process { $_.Name }
Run Code Online (Sandbox Code Playgroud)
基于member-enumeration/property-name的集合方法解决方案比最快的基于管道的解决方案快10倍.
该10,000
声明的解决方案是大约2.5速度较慢,但仍有约4-5倍的速度最快的管道解决方案.
使用带有集合方法解决方案()的脚本块Get-ChildItem
会大大减慢速度,因此它几乎与最快的基于管道的解决方案([pscustomobject]
)相当.
Convert-FromCsv
([pscustomobject]
好奇地,表现最差,即使%
是概念等同于ForEach-Object
).
测试的源代码:
注意:[pscustomobject]
从此Gist下载函数以运行这些测试.
# By property name (string):
$objects.ForEach('Name')
# By script block (more flexibility; like ForEach-Object)
$objects.ForEach({ $_.Name })
Run Code Online (Sandbox Code Playgroud)