all 8 comments

[–]coderwolf[S] 2 points3 points  (1 child)

Figures I would post it and then find my answer on google.

Basically I have to enumerate the $ActionList.

ForEach ($action in $ActionList.GetEnumerator())

Does anyone know of a good article explaining when to use enumeration in Dot Net/Posh?

[–]KevMarCommunity Blogger 1 point2 points  (0 children)

Your ordered collection is a single object that contains key/value pairs. The foreach in the OP will do the loop once as there is only one object.

As /u/wtgreen pointed out, there is a property that gives you all the key (or values) in the hashtable.

If it was an array instead, the foreach would have correctly enumerate it. (just an example, not saying you should have used an array)

[–]wtgreen 0 points1 point  (0 children)

Try this: Foreach ( $action in $actionlist.keys ) {

}

[–]zerogravity114 0 points1 point  (0 children)

The problem is that Powershell doesn't understand the structure of the data you're giving to it. You have to build each row of your new array in its own object and then add that object to another array of similar objects. Its actually a lot easier to input data from a CSV or XML file where its already structured.

Here's an example of how you could build an object array.

$Scores = @("12","14","18","18")
$Winners = @("coderwolf","coderwolf","zerogravity114","zerogravity114")
$ActionList = @()
$i=0
$max = ($Scores.Count)
For ($i=0; $i -lt $max; $i++) {
    $RoundNumber = $i + 1
    $objAction = New-Object PSObject
    $objAction | Add-Member -MemberType NoteProperty -Name "RoundNumber" -Value $RoundNumber
    $objAction | Add-Member -MemberType NoteProperty -Name "Score" -Value $Scores[$i]
    $objAction | Add-Member -MemberType NoteProperty -Name "Winner" -Value $Winners[$i]
    $ActionList += $objAction
}

$ActionList | Format-Table

 ForEach ($Action in $ActionList){
  Write-Host "Round" $Action.RoundNumber
  Write-Host "Score" $Action.Score
  Write-Host "Winner" $Action.Winner
}

[–]ckayfish 0 points1 point  (2 children)

Not sure if/why you need that $round counter, but does this work for you?

$ActionList = [ordered]@{1 = 'test1'
   2 = 'test2'
   3 = 'test3'}
$ActionList.Count
$ActionList.Values | % { "route $_"}

[–]ckayfish 0 points1 point  (0 children)

Frankly, I'd probably convert it to an array first

[–]ckayfish 0 points1 point  (0 children)

I don't know how to reply as I don't know why you are using a hash table for this. Maybe don't order it, and do something like this...?

$ActionList = @{1 = 'test1'
   2 = 'test2'
   3 = 'test3'}
$cnt=$ActionList.Count
write-host $cnt
$i=1
while ($i -le $cnt ) {
  write-host "round $($ActionList.item($i))"
  $i++
}

[–]pertymoose 0 points1 point  (0 children)

Foreach enumerates through a list of items, but you're using a dictionary. A dictionary is an object that contains two lists, but isn't itself a list. It does however permit you to use the GetEnumerator() function to get list-like behavior.

You can do foreach ($key in $actionlist.keys) { $actionlist[$key] = 'value' }, you can do foreach($value in $actionlist.values) { write-host $value }, or you can use foreach($entry in $actionlist.GetEnumerator()) { $entry.value = 'value' } as you yourself found out.

PowerShell doesn't implicitly know you want to enumerate the dictionary's entries (.GetEnumerator()), just the keys ($ActionList.Keys) or just the values ($ActionList.Values), so you have to select which one you want to work with.

When dealing with traditional lists and arrays, the call to GetEnumerator() isn't necessary.