Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell: Filter Hashtable - and get back a Hastable

Filtering a Hashtable using GetEnumerator always returns a object[] instead of a Hashtable:

# Init Hashtable
$items = @{ a1 = 1; a2 = 2; b1 = 3; b2 = 4}
# apply a filter
$filtered = $items.GetEnumerator() | ?{ $_.Key -match "a.*" }
# The result looks great
$filtered
  Name                           Value
  ----                           -----
  a2                             2
  a1                             1
# … but it is not a Hashtable :-(
$filtered.GetType()
  IsPublic IsSerial Name                                     BaseType
  -------- -------- ----                                     --------
  True     True     Object[]                                 System.Array

Is there a nice solution to this problem?

Thanks a lot for any Help!, kind regards, Tom

like image 608
Tom Avatar asked Mar 03 '16 21:03

Tom


People also ask

How do I get key value pairs in PowerShell?

The key/value pairs might appear in a different order each time that you display them. Although you cannot sort a hash table, you can use the GetEnumerator method of hash tables to enumerate the keys and values, and then use the Sort-Object cmdlet to sort the enumerated values for display.

How do I iterate through a Hashtable in PowerShell?

In the first method, the one that I prefer, you can use the GetEnumerator method of the hash table object. In the second method, instead of iterating over the hash table itself, we loop over the Keys of the hash table. Both of these methods produce the same output as our original version.

What is GetEnumerator in PowerShell?

GetEnumerator. A hash table is a single PowerShell object, to sort, filter or work with the pipeline you can unwrap this object into it's individual elements with the GetEnumerator() method.

How do I merge two hash tables in PowerShell?

Adding values of the hash table is simple as the adding string. We just need to use the addition operator (+) to merge two hash table values.


1 Answers

$filtered is an array of dictionary entries. There's no single cast or ctor for this as far as I know.

You can construct a hash though:

$hash = @{}
$filtered | ForEach-Object { $hash.Add($_.Key, $_.Value) }

Another workflow:

# Init Hashtable
$items = @{ a1 = 1; a2 = 2; b1 = 3; b2 = 4}

# Copy keys to an array to avoid enumerating them directly on the hashtable
$keys = @($items.Keys)
# Remove elements not matching the expected pattern
$keys | ForEach-Object {
    if ($_ -notmatch "a.*") {
        $items.Remove($_)
    }
}

# $items is filtered
like image 66
briantist Avatar answered Oct 09 '22 03:10

briantist