我对PowerShell如何对待哈希键和对象属性感到困惑。
考虑:
$list = @{
'one' = @{
name = 'one'
order = 80
};
'two' = @{
name = 'two'
order = 40
};
'twotwo' = @{
name = 'twotwo'
order = 40
};
'three' = @{
name = 'three'
order = 20
}
}
$list.Values|group-object { $_.order }
$list.Values|group-object -property order第一个组-对象给了我所期望的(三个组),第二个组没有(一个大组)。显然,哈希键不是对象属性,而是以相同的方式(var.name)引用它们。
第二组对象到底在做什么?
它认为“订单”财产是什么?
发布于 2018-02-28 18:56:41
这是可以理解的混淆,但正如您所说的,哈希表键不是对象属性。
同样地对待他们是很有诱惑力的(有时也是这样),但这种情况肯定不会。
部分原因是因为您使用的是不同的cmdlet,而不是直接的语言语义。
哈希表可以对其键使用点表示法,但键不是属性,当您使用-Property参数Group-Object时,您需要的是具体的属性,而不仅仅是“您可以用点访问的任何东西”。
如您所见,采用scriptblock的参数的另一种形式是将被执行的代码,因此无论块返回的值是什么,它都将被分组。
要更直接地回答你的问题:
第二组对象到底在做什么?
它正在寻找当前对象(这是一个哈希表)上的一个属性(特别是)。
如果要查看其中一个对象上的属性是什么样子,请尝试如下:
$list.Values[0].PSObject.Properties | ft它认为“订单”财产是什么?
它不认为它是任何东西;它寻找一个具有这个名称的属性,如果它找到一个属性,它就使用这个值;否则它就使用$null。
您将得到同样的结果:
$list.Values | group -Property FakeProp或
$list.Values | group -Property { $null }在评论中回答你的问题:
有什么方法可以知道“什么时候应该”和“什么时候不应该”,我应该只考虑使用脚本块吗?-Property的使用什么时候比{. }更好?
只要您想要分组的值作为被检查对象的直接属性可用,-Property (没有脚本块)是首选的。如果它是属性的属性,或者某个计算值,或者一个哈希表键/值,或者其他任何东西,请使用scriptblock。我称之为“复杂值”。
如果复合值有用,您可能希望将其添加为对象本身的实际属性来封装它;然后可以直接引用它。这个示例并不适合您的哈希表情况,但是要考虑表示人的对象。它们有两个属性:Name和DateOfBirth。
$people是这些对象的数组,您希望按年龄分组(请忽略我不准确的年龄确定代码)。
$people | Group-Object -Property { ([DateTime]::Now - $_.DateOfBirth).Days / 365 -as [int] }如果你再也不需要知道年龄,那也没关系;当然,这是不太可能的,而且这看起来有点混乱。你想要“按年龄分组”,这一点应该更直接一些。
相反,您可以将自己的(计算) Age属性添加到具有Add-Member的现有对象中。
$people |
Add-Member -MemberType ScriptProperty -Name Age -Value {
([DateTime]::Now - $this.DateOfBirth).Days / 365 -as [int]
} -Force从现在开始,$people数组中的每个对象都有一个基于DateOfBirth属性值计算的Age属性。
现在,您可以使代码更清晰:
$people | Group-Object -Property Age同样,这并没有真正解决您的hashtable问题;事实是,它们对于分组没有那么好的工作。如果要与它们进行大量分组,并且不需要散列表,请将它们变成对象:
$objs = $list.Values |
ForEach-Object -Process {
New-Object -TypeName PSObject -Property $_ # takes a hashtable
}或
$objs = $list.Values |
ForEach-Object -Process {
[PSCustomObject]$_ # converts a hashtable to PSObject
}然后:
$objs | Group-Object -Property Orderhttps://stackoverflow.com/questions/49036466
复制相似问题