schuelermine
schuelermine

Reputation: 2288

Select multiple properties where one of the properties must be unique in a pipeline

Using Select-Object, you can select the first of multiple occurences of an object using -Unique. You can also select only some properties to be retained. But what if I want to check for the uniqueness of only one property, filter out all non-unique ones and not just leave one of them, and allow the other properties to pass through unchanged? Specifically, I have a list of PSCustomObjects where one property is a base name, and another is a shortened name generated automatically. I want to filter out elements where the short name occurs multiple times, but the base names of all items are all different. It seems Select-Object isn't a match for this task, but what is?

EDIT: To clarify - this should be the result:

> $A = [PSCustomObject]@{A = 1; B = 2}, [PSCustomObject]@{A = 2; B = 2}, [PSCustomObject]@{A = 4; B = 1}
> $A

A B
- -
1 2
2 2
4 1

> $A | Mystery-Cmdlet "B"

A B
- -
4 1

Upvotes: 0

Views: 536

Answers (2)

JosefZ
JosefZ

Reputation: 30123

I have a list of PSCustomObjects…
I want to check for the uniqueness of only one property, filter out all non-unique ones and not just leave one of them, and allow the other properties to pass through unchanged…

Let's rewrite above requirements in terms of PowerShell cmdlets:

$A = @'
A,B
1,2
2,2
4,1
5,4
'@ | ConvertFrom-Csv -Delimiter ','        # a list of PSCustomObjects

$A |
  Group-Object -Property B |               # check for the uniqueness,
    Where-Object Count -eq 1 |             # filter out all non-unique ones,
      Select-Object -ExpandProperty Group  # and pass through the rest unchanged

Output: 62219608.ps1

A B
- -
4 1
5 4

Upvotes: 3

Farbkreis
Farbkreis

Reputation: 644

I think you have to resolve it with code

$A = [PSCustomObject]@{A = 1; B = 2}, [PSCustomObject]@{A = 2; B = 2}, [PSCustomObject]@{A = 4; B = 1}

$A | Add-Member -NotePropertyName Count -NotePropertyValue init

for ($i=0; $i -lt $a.Length; $i++) {
$a[$i].Count = ($A.B | Where-Object {$_ -eq $a[$i].B}).Count
}

$a | Where-Object {$_.Count -eq 1}

Upvotes: 1

Related Questions