Home > Mobile >  Return an array of unique objects which are specified by properties using PowerShell
Return an array of unique objects which are specified by properties using PowerShell

Time:12-25

I have an object converted from JSON which contains information about 'Trusted clients'. There are two properties one of which identifies the uniqueness of a client: Name AND Thumbprint, so if there are elements, either contain the same Name or Thumbprint, they must be omitted.

Also, I'd like to point that output array should contain additional property - Id which could be generated with - New-Guid. That particular case was discussed here: enter link description here.

{
  "TrustedClients": [
        {
            "Name": "Client1",
            "Thumbprint": "5ed7eb688e404bd787585637975ddb01",
            "CallbackThumbprint": "b7f610106fa24afe9460ab8e4f2db1fc"
        },
        {
            "Name": "Client2",
            "Thumbprint": "5ed7eb688e404bd787585637975ddb01",
            "CallbackThumbprint": "b7f610106fa24afe9460ab8e4f2db1fc"
        },
        {
            "Name": "Client3",
            "Thumbprint": "1700a8497495d6053be04b690b98479fd62e6cc9",
            "CallbackThumbprint": "b7f610106fa24afe9460ab8e4f2db1fc"
        }
    ]
}

Is there an efficient way to get an array of unique objects specified by Name AND Thumbprint properties? So in that case the output array should contain only one object with name Client3 since there are two elements with the same Thumbprint value:

{
  "TrustedClients": [
        {
            "Id": "{(New-Guid).ToString()}"
            "Name": "Client3",
            "Thumbprint": "1700a8497495d6053be04b690b98479fd62e6cc9",
            "CallbackThumbprint": "b7f610106fa24afe9460ab8e4f2db1fc"
        }
    ]
}

I was tweaking with grouping at first, but it conflicts with the basic idea - uniqueness by Name AND Thumbprint. It's became obvious that grouping elements by Name AND Thumbprint potentially could return array with different Name values, but the same Thumbprint and vice versa.

CodePudding user response:

So, unique Name and Thumbprint, the way I see around it to keep it efficient was to use a hashtable or dictionary, not only for efficiency but also because Keys needs to be removed if there ever is a Name or Thumbprint that was added before.

Since I'm a total noob with classes I decided to use one for practicing purposes :)

using namespace System.Collections.Generic

class UniqueJSON {
    [Dictionary[string,object]]$Ref = [Dictionary[string,object]]::new()

    [Void]AddList([pscustomobject[]]$Items) {
        foreach($item in $Items)
        {
            $containsKey = $this.Ref.Keys -contains $Item.ThumbPrint
            $containsVal = $this.Ref.Values.Keys -contains $Item.Name
            if($containsKey -or $containsVal)
            {
                $this.Ref.Remove($Item.ThumbPrint)
                continue
            }

            $item.PSObject.Properties.Add(
                [psnoteproperty]::new(
                    'ID', [guid]::NewGuid().Guid
                )
            )

            $this.Ref[$Item.ThumbPrint] = @{
                $Item.Name = $Item
            }
        }
    }

    [object[]]Get() {
        return $This.Ref.Values.Values
    }
}

# Here you can import your JSON
$json = ..... | ConvertFrom-Json

# Now store the TrustedClients property in a variable
$trusted = $json.TrustedClients

# Create a new instance of the class
$instance = [UniqueJSON]::new()

# Add $trusted
$instance.AddList($trusted)

# Get the unique results
$instance.Get()
  • $instance.Get() returns:
Name    Thumbprint                               CallbackThumbprint               ID
----    ----------                               ------------------               --
Client3 1700a8497495d6053be04b690b98479fd62e6cc9 b7f610106fa24afe9460ab8e4f2db1fc 85af5623-365c-4f8a-9863-be38860406da
  • Related