假设我有以下内容:
$x = @()
$x += [pscustomobject]@{
a=1
b=2
c=[pscustomobject]@{
a=1
b=2
}
}
$x += [pscustomobject]@{
a=1
b=2
c=[pscustomobject]@{
a=3
b=4
}
}
$x | Select * -Unique
我期望的行为是返回$x
内的两个对象,因为$x.c
包含唯一项。我不能简单地运行$x.c | Select * -Unique
,因为我想存储和关联整个对象。
上面的代码,不管确切的对象是什么,仅返回第一个对象。
有没有一种方法可以产生我想要的行为而不只是展平所有对象?
使用invoke-expression的潜在非常混乱的解决方案:
$a = $x | gm | ? {$_.MemberType -eq 'NoteProperty' -and $_.Definition -like '*object*'} | select -ExpandProperty Name
$y = @()
$a | %{
$p = $_
$x.$p | gm | ? {$_.MemberType -eq 'NoteProperty'} | select -ExpandProperty Name | % { $y += "{`$_.$p.$_}" }
}
$y = ($y | convertto-json -Compress) -replace '\[' -replace '\]' -replace '\"'
iex -command ('$x | Sort (iex $y) -Unique |Select *')
答案 0 :(得分:1)
如果要区分c
的属性,请首先使用Sort-Object
:
$x |Sort {$_.c.a},{$_.c.b} -Unique |Select *
答案 1 :(得分:0)
我想到了这一点,即排序对象可以使用脚本块来区分属性。我基本上只是拉出所有我感兴趣的属性,创建脚本块,然后将其添加到数组中。
$itemsToExpand = $x | Get-Member | Where-Object {$_.MemberType -eq 'NoteProperty' -and $_.Definition -like '*object*'} | Select-Object -ExpandProperty Name
$scriptBlockArray = @()
$itemsToExpand | ForEach-Object{
$current = $_
$x.$current | Get-Member | Where-Object {$_.MemberType -eq 'NoteProperty'} | Select-Object -ExpandProperty Name | ForEach-Object {
$scriptBlockArray += [Scriptblock]::Create("`$_.$current.$_")
}
}
$x | Sort-Object $scriptBlockArray -Unique