2

Lets say I have a serious of objects (in pscustomObject or Hashtables) and I need to reference them dynamically, as is it the user that is deciding what data to access.

....
$sweden = [PSCustomObject]@{monday = "sunny" ; tuesday = "sunny" ; wednesday = "sunny" ; thursday = "sunny" ; friday = "sunny"}
$siberia    = [PSCustomObject]@{monday = "cold" ; tuesday = "cold" ; wednesday = "cold" ; thursday = "cold" ; friday = "cold"}
$turkey = [PSCustomObject]@{monday = "unknown" ; tuesday = "unknown" ; wednesday = "cold" ; thursday = "cold" ; friday = "cold"}
$england = [PSCustomObject]@{monday = "miserable" ; tuesday = "miserable" ; wednesday = "miserable" ; thursday = "miserable" ; friday = "miserable"}
....

The user is meant to pass his value to the $country variable, I then need to access corresponding data pool. Something like the following:

$country = 'england'
$("$country").monday #this should print "miserable"

Running the above, nothing happens, no errors. The prompt returns, that is it. I also tried it without the quotes, $($country).monday.

pwsh 7.4/win11

3
  • 2
    this is something you can easily solve using a hashtable, $countries['england'].monday or, by user input, $countries[$country].monday Commented Jul 9 at 21:34
  • 3
    What you're looking for is variable indirection, where you refer to a variable indirectly, via its name stored in a different variable or provided by an expression. PowerShell enables this via the Get-Variable and Set-Variable cmdlets, but note that there are usually better alternatives, such as hashtables, as shown in Santiago's answer.
    – mklement0
    Commented Jul 9 at 21:57
  • 1
    You can use Get-Variable to retrieve a named variable from a string - e.g. $variable_name = "sweden"; $dynamic_value = (Get-Variable -Name $variable_name).Value but this sort of meta-programming / reflection is going to tie you in knots in the long run. @SantiagoSquarzon's answer below is a better option...
    – mclayton
    Commented Jul 9 at 21:58

1 Answer 1

4

Use a single hashtable instead of multiple variables to reference your countries:

$countries = @{
    sweden  = [PSCustomObject]@{monday = 'sunny' ; tuesday = 'sunny' ; wednesday = 'sunny' ; thursday = 'sunny' ; friday = 'sunny' }
    siberia = [PSCustomObject]@{monday = 'cold' ; tuesday = 'cold' ; wednesday = 'cold' ; thursday = 'cold' ; friday = 'cold' }
    turkey  = [PSCustomObject]@{monday = 'unknown' ; tuesday = 'unknown' ; wednesday = 'cold' ; thursday = 'cold' ; friday = 'cold' }
    england = [PSCustomObject]@{monday = 'miserable' ; tuesday = 'miserable' ; wednesday = 'miserable' ; thursday = 'miserable' ; friday = 'miserable' }
}

$country = 'england'
$countries[$country].monday # this should print "miserable"

The alternative if using multiple variables to dynamically reference it, is to use Get-Variable, which really does feel miserable:

$country = 'england'
(Get-Variable $country -ValueOnly).monday

Not the answer you're looking for? Browse other questions tagged or ask your own question.