描述:我正在构建一个PowerShell脚本来搜索文件,然后给它们唯一的名称,复制它们然后通过哈希计算验证它们 - 我选择在每个步骤的函数中拆分脚本,因此更容易维护整件事情.为了从一个函数到另一个函数获取所有值,我选择使用[hashtable]$FooBar
- inside $FooBar
,有多个数组,例如FullName
或OutputPath
(可能会更改每个文件,因为它们将被复制到命名的子文件夹yyyy-mm-dd
).所有数组都相互关联(意味着索引1包含第一个文件的所有值,索引2包含第二个文件的值,...),这在现在工作正常.
短简化可视化:
$FooBar = @{}
$FooBar.FullName = @()
$FooBar.Size = @()
$FooBar.Ext = @()
Get-ChildItem | ForEach-Object {
$FooBar.FullName += $_.FullName
$FooBar.Size += $_.Length
$FooBar.Ext += $_.Extension
}
但是,我现在需要通过其中一个数组的一个值集对它们进行排序,例如大小.或者,再次可视化:
# From:
$FooBar
Name Value
---- -----
fullname {D:\AAA.XYZ, D:\BBB.ZYX, D:\CCC.YZX}
size {222, 111, 555}
extension {.XYZ, .ZYX, .YZX}
# To:
$FooBar = $FooBar | Sort-Object -Property Size -Descending
$FooBar
Name Value
---- -----
fullname {D:\CCC.YZX, D:\AAA.XYZ, D:\BBB.ZYX}
size {555, 222, 111}
extension {.YZX, .XYZ, .ZYX}
我试过了$FooBar.GetEnumerator() | Sort-Object -Property Size
,但这并没有改变任何事情.Google提出了如何对一组哈希表进行排序的建议,但在我的情况下,反之亦然,我无法理解这一点,因为我甚至不理解为什么这是一个问题.
所以我的问题是:有没有办法通过其中一个数组的值集对哈希表中的所有数组进行排序?我无法理解这一点.
免责声明:我是一个PowerShell-autodidact,在脚本/编程方面没有合理的背景,所以很可能我的"将所有东西都包含在一个散列表中"-solution根本不起作用或者效率极低 - 如果是这样的话, 请告诉我.
1> Patrick Mein..:
我认为你想要做的最简单的方法是 Select-Object
$fooBar = Get-ChildItem | Select-Object FullName, Size, Extension
这将创建一个只具有所需属性的新对象数组.这种方法起作用的原因并不是因为Sort-Object适用于属性,而您指定的属性位于几个层之后.
如果您需要比精确属性更多的灵活性,您可以像这样创建自己的灵活性
$fooBar = Get-ChildItem | Select-Object @{Name = 'SizeMB'; Expression = {$_.Size / 1MB}}
或者使用[PSCustomObject]
类型加速器手动创建新属性:
$fooBar = Get-ChildItem | ForEach-Object {
[PSCustomObject]@{
FullName = $_.FullName
Extension = $_.Extension
Size = $_.Size
}
}
更新
如果您需要在最初创建对象后向对象添加其他属性,则可以选择一些选项.
加入会员
到目前为止,最常用的方法是使用Add-Member
cmdlet.
$object | Add-Member -MemberType NoteProperty -Name NewProperty -Value 'MyValue'
$object
要记住的重要一点是,默认情况下,此cmdlet不会返回任何内容.因此,如果将上述语句放在函数的末尾并且不单独返回该对象,则函数将不返回任何内容.确保您使用-PassThru
参数(这对链接Add-Member
命令也很有用)或之后调用变量(如上例所示)
选择-对象
使用计算属性添加成员时,可以选择所有以前的属性.请记住,由于Select-Object
工作方式的原因,源对象中的所有方法都不会被转移.
$fooBar | Select-Object *, @{Name = 'NewProperty'; Expression = {'MyValue'}}
psobject.Properties
这个是我个人最喜欢的,但它仅限于PowerShell的更高版本,我还没有看到它被其他任何人使用过.
$fooBar.psobject.Properties.Add([psnoteproperty]::new('NewProperty', 'MyValue'))
$fooBar
每个成员类型都有自己的构造函数.您还可以添加方法$fooBar.psobject.Methods
或键入到$fooBar.psobject.Members
.我喜欢这种方法,因为它感觉更明确,而且添加成员与成员的感觉是正确的.
摘要
您选择的方法主要是偏好.Add-Member
如果可能,我会建议,因为它是最常用的,因此具有更好的可读性和更多可以回答有关它的问题的人.
我还想提一下,如果可能的话,通常最好避免添加额外的成员.理想情况下,函数的返回值应具有可靠的形式.如果有人正在使用您的函数,并且他们必须猜测对象上何时存在属性或方法,则调试变得非常困难.显然这不是一个硬性规则,但如果你需要添加一个成员,你至少应该考虑改造是否更好.