首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >powershell哈希表密钥与对象属性

powershell哈希表密钥与对象属性
EN

Stack Overflow用户
提问于 2018-02-28 18:44:00
回答 1查看 1.3K关注 0票数 2

我对PowerShell如何对待哈希键和对象属性感到困惑。

考虑:

代码语言:javascript
复制
$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)引用它们。

第二组对象到底在做什么?

它认为“订单”财产是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-28 18:56:41

这是可以理解的混淆,但正如您所说的,哈希表键不是对象属性。

同样地对待他们是很有诱惑力的(有时也是这样),但这种情况肯定不会。

部分原因是因为您使用的是不同的cmdlet,而不是直接的语言语义。

哈希表可以对其键使用点表示法,但键不是属性,当您使用-Property参数Group-Object时,您需要的是具体的属性,而不仅仅是“您可以用点访问的任何东西”。

如您所见,采用scriptblock的参数的另一种形式是将被执行的代码,因此无论块返回的值是什么,它都将被分组。

要更直接地回答你的问题:

第二组对象到底在做什么?

它正在寻找当前对象(这是一个哈希表)上的一个属性(特别是)。

如果要查看其中一个对象上的属性是什么样子,请尝试如下:

代码语言:javascript
复制
$list.Values[0].PSObject.Properties | ft

它认为“订单”财产是什么?

它不认为它是任何东西;它寻找一个具有这个名称的属性,如果它找到一个属性,它就使用这个值;否则它就使用$null

您将得到同样的结果:

代码语言:javascript
复制
$list.Values | group -Property FakeProp

代码语言:javascript
复制
$list.Values | group -Property { $null }

在评论中回答你的问题:

有什么方法可以知道“什么时候应该”和“什么时候不应该”,我应该只考虑使用脚本块吗?-Property的使用什么时候比{. }更好?

只要您想要分组的值作为被检查对象的直接属性可用,-Property (没有脚本块)是首选的。如果它是属性的属性,或者某个计算值,或者一个哈希表键/值,或者其他任何东西,请使用scriptblock。我称之为“复杂值”。

如果复合值有用,您可能希望将其添加为对象本身的实际属性来封装它;然后可以直接引用它。这个示例并不适合您的哈希表情况,但是要考虑表示人的对象。它们有两个属性:NameDateOfBirth

$people是这些对象的数组,您希望按年龄分组(请忽略我不准确的年龄确定代码)。

代码语言:javascript
复制
$people | Group-Object -Property { ([DateTime]::Now - $_.DateOfBirth).Days / 365 -as [int] }

如果你再也不需要知道年龄,那也没关系;当然,这是不太可能的,而且这看起来有点混乱。你想要“按年龄分组”,这一点应该更直接一些。

相反,您可以将自己的(计算) Age属性添加到具有Add-Member的现有对象中。

代码语言:javascript
复制
$people |
    Add-Member -MemberType ScriptProperty -Name Age -Value {
        ([DateTime]::Now - $this.DateOfBirth).Days / 365 -as [int]
    } -Force

从现在开始,$people数组中的每个对象都有一个基于DateOfBirth属性值计算的Age属性。

现在,您可以使代码更清晰:

代码语言:javascript
复制
$people | Group-Object -Property Age

同样,这并没有真正解决您的hashtable问题;事实是,它们对于分组没有那么好的工作。如果要与它们进行大量分组,并且不需要散列表,请将它们变成对象:

代码语言:javascript
复制
$objs = $list.Values |
    ForEach-Object -Process {
        New-Object -TypeName PSObject -Property $_ # takes a hashtable
    }

代码语言:javascript
复制
$objs = $list.Values |
    ForEach-Object -Process {
        [PSCustomObject]$_ # converts a hashtable to PSObject
    }

然后:

代码语言:javascript
复制
$objs | Group-Object -Property Order
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49036466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档