Sort hashtable containing arrays - Powershell - powershell

I am trying to sort an hashtable in Powershell with the following structure :
https://i.stack.imgur.com/bjSX6.png
Each value of the hashtable is an array containing multiple elements.
I would like to sort the hashtable based on the value of second element of each array, is it possible ?

Create an ordered dictionary, then enumerate all the key-value pairs in the existing hashtable, sort them by the desired value and then add them to your new ordered dictionary:
# Create ordered dictionary
$ordered = [ordered]#{}
# Sort KVPs by value at index 1 (that's the second element) of the array
$hashtable.GetEnumerator() |Sort-Object { $_.Value[1] } |ForEach-Object {
# Copy the KVP to the ordered dictionary in... order
$ordered[$_.Key] = $_.Value
}
$ordered now contains the same entries as $hashtable, but sorted according to your criteria

Related

Match key to value between 2 hash tables - Powershell

Apologies I am not clued up with PowerShell just yet.
I have two hash tables, one containing the label name and the ID. The other contains a folder path and the label name.
I am trying to extract the label ID e.g 'e58e1e18-da7e-493c-9961-a7deff6dc7f7' to use in a for each statement.
I am looping through the folder's hash table, and need to be able to match the folder key with the label value, if there is a match, extract that value from the labels hash.
Example: 'C:\OTD\Cat' would have the id of 'e58e1e18-da7e-493c-9961-a7deff6dc7f7' as Label1 matches in both hash tables.
$labels = #{
'Label1' = 'e58e1e18-da7e-493c-9961-a7deff6dc7f7'
'Label2' = '6514c00d-001e-4041-9207-f31aebc5e13a'
'Label3' = 'e58e1e18-da7e-493c-9961-a7deff6dc7f7'
}
$folders = #{
'C:\OTD\Cat' = 'Label1'
'C:\OTD\Dog' = 'Label2'
'C:\OTD\Frog' = 'Label3'
}
# Match key/value in a hashtable and return the labels id value
$folders.GetEnumerator() | ForEach-Object{
If($_.value = matches key name in labels hash, grab that label ID to use here)
}
Thank you for looking at my question!
Use the corresponding values as index keys for the second hashtable:
$folders.Keys | % {
# Grab the label
$folderLabel = $folders[$_]
# Use label as key to resolve label ID
$labelId = $labels[$folderLabel]
}
You can nest these as crazily as you want (although it might hurt readability of your code):
$labelIDs = $folders.Keys | % {
$labels[$folders[$_]]
}
As a side note, I recommend iterating through dictionaries as lists of key-value pairs by explicitly calling GetEnumerator() instead of iterating over Keys:
$folders.GetEnumerator() |%{
$folderPath = $_.Key
$folderLabel = $_.Value
$labelID = $labels[$_.Value]
}

How to display hash table's values by delivering a array consist of hash table's keys in powershell?

$hash = #{}
$hash.x1 = 1
$hash.x2 = 2
Can I display the hash table's values like this?
$hash.[x1,x2]
$hash.[x1,x2] (with dot and bare words) will not work, but you can use the index operator directly on a hashtable with an array of the key names (as strings). Like this:
$hash['x1','x2']
or like this:
$keys = 'x1', 'x2'
$hash[$keys]

Dynamically create arrays from an existing arrays values in PowerShell

In PowerShell I have a array of unique values, e.g. "London Office", "Manchester Office" etc.
What I need to do is create a new array for every value inside the original array, where the name of each array is the value in the original array. I.e. so that the name of each array is:
"London Office", "Manchester Office" etc.
This would seem simple but is stumping me, any help much appreciated.
Use Set-Variable cmdlet. Or, create a global hash table and stuff arrays in its entries with keys from your initial array.
Sounds like you need a hashtable - basically an unordered dictionary:
$Array = "London Office", "Manchester Office"
# Create an empty hashtable
$Hashtable = #{}
foreach($item in $Array){
# create hashtable entry with array $item as key/name, empty array as value
$Hashtable[$item] = #()
}
Now you can access the individual arrays like this:
$Hashtable["Manchester Office"] += "New array item here"

Create array from keys of an array of hashtables

I have an array where each element is a hashtable. Each hashtable has the same keys. Here it is:
#(
#{"MarketShortCode"="abc";"MarketName"="Market1" },
#{"MarketShortCode"="def";"MarketName"="Market2" },
#{"MarketShortCode"="ghi";"MarketName"="Market3" },
#{"MarketShortCode"="jkl";"MarketName"="Market4" }
)
I want a nice elegant way to extract an array containing just the value of the MarketShortCode key. So I want this:
#("abc","def","ghi","jkl")
This is the best I've come up with:
$arr = #()
$hash | %{$arr += $_.MarketShortCode}
$arr
But I don't like that cos its three lines of code. Feels like something I should be able to do in one line of code. Is there a way?
Just do this:
$hash | %{$_.MarketShortCode}
That is, return the value from the block instead of adding it to an array and then dereferencing the array.
If you're using PowerShell 3+, there's even shorter way:
$hash.MarketShortCode
PowerShell automatically applies dot . to each item in an array when it's used this way, but it wasn't supported until v3.

How to create KeyCollection from array in Powershell?

Let's say I have hash like this:
$NATO = #{
"A" = "Alpha";
"B" = "Bravo";
"C" = "Charlie";
# ...
"Y" = "Yankee";
"Z" = "Zulu";
}
I could get all values of hash using $NATO.keys key collection:
$NATO[$NATO.keys] # gives me all values
But if I want to pass subset of keys, to get subset of values, I can't do that:
$NATO["BUNYK".ToCharArray()] # gives me nothing, but I want
# Bravo, Uniform, November, Yankee, Kilo
Do you know how this could be done?
You could also pipe the string array into a ForEach-Object loop:
[string[]]'BUNYK'.ToCharArray() | % { $NATO[$_] }
The hash table stores the keys as objects, not necessarily simple strings. The keys in your example are strings, but you're trying to access them as [char] objects. The easiest way to handle your example is to cast the [char[]] array to a [string[]] array:
$NATO[([string[]] "BUNYK".ToCharArray())]