0

I'm looking for some clean and efficient way to compare arrays stored in hashtable, without iterating over them ideally. Also without harcoding the keys

The hashtable:

Key   : somekey1
Value : {value1, value2, value3, value4}
Name  : somekey1

Key   : somekey2
Value : {value1, value2, value3}
Name  : somekey2

created with:

$hashtable = @{};

$hashtable[somekey1] = @();
$hashtable[somekey2] = @();
$hashtable[somekey3] = @();

ForEach ($key in $hashtable.keys)
{
$hashtable[$key] += value1;
}

I would like to call something like:

Compare-Object $($hashtable.keys)[0] $($hashtable.keys)[1] -Property Value;

and the expected output would be

value4

Is this possible? (asking as a PowerShell newbie)

10
  • A hashtable like: @{ somekey1 = 'value1', 'value2', 'value3', 'value4'; somekey2 = 'value1', 'value2', 'value3' } or actually a PSCustomObject/object list? Please try to create a minimal reproducible example in your question. Commented Aug 31, 2022 at 7:15
  • A hastable (i guess) - Iam declaring it as a hastable: $hashtable = @{}; and then adding arrays like $hashtable[somekey1] = @(); -> then filling with $hashtable[somekey1] +1 value1; Commented Aug 31, 2022 at 7:20
  • Thus: $HashTable = @{ somekey1 = 'value1', 'value2', 'value3', 'value4'; somekey2 = 'value1', 'value2', 'value3' } ; Compare-Object $HashTable.somekey1 $HashTable.somekey2? if that doesn't answer the question, I suggest you edit your question and add an actual example (not a description) of how you create the hashtable. Commented Aug 31, 2022 at 7:35
  • The point of this question is doing this without hardcoding key names. I've edited the question :) Commented Aug 31, 2022 at 7:49
  • Hashtables are unordered by nature. You need an ordered dictionary to be able to get the values by index (rather than key name): $Ordered = [ordered]@{ somekey1 = 'value1', 'value2', 'value3', 'value4'; somekey2 = 'value1', 'value2', 'value3' } ; Compare-Object $Ordered[0] $Ordered[1]. Or do you want compare each key with any other key? Commented Aug 31, 2022 at 8:24

1 Answer 1

2

Assuming each array only contains unique values, you can use the [HashSet[string]] class to calculate the difference between two sets of strings:

# Define hashtable
$hashtable = @{
  somekey1 = @('value1', 'value2', 'value3', 'value4')
  somekey2 = @('value1', 'value2', 'value3')
  somekey3 = @()
}

# Copy key collection
$keys = @($hashtable.psbase.Keys)

# Nested loops to compare each unique key pair
for($i = 0; $i -lt $keys.Count - 1; $i++){
  for($j = $i + 1; $j -lt $keys.Count; $j++){
    # Pick next two keys to compare
    $k1,$k2 = $keys[$i,$j]

    # Calculate symmetric difference of associated arrays
    $delta = [System.Collections.Generic.HashSet[string]]::new([string[]]$hashtable[$k1])
    $delta.SymmetricExceptWith([string[]]@($hashtable[$k2]))

    # Output comparison results
    [pscustomobject]@{
        RefKey = $k1
        DiffKey = $k2
        Delta = $delta
    }
  }
}

HashSet.SymmetricExceptWith will calculate the symmetric difference between the two sets (the strings that are in one but not both), giving an output for the sample values like this:

RefKey   DiffKey  Delta
------   -------  -----
somekey1 somekey3 {value1, value2, value3, value4}
somekey1 somekey2 {value4}
somekey3 somekey2 {value1, value2, value3}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.