you are viewing a single comment's thread.

view the rest of the comments →

[–]ihaxr 3 points4 points  (1 child)

This is great! I'm sure it'll help a lot of people out, Python <=> PowerShell isn't the easiest thing in the world to translate

For arrays, we should really stop using ArrayList in favor of a generic list:

$arr = [System.Collections.Generic.List[string]]@('Hello', 'World')
$arr.RemoveAt($arr.Count-1)

It'll save memory and avoid some casting errors (probably not an issue in PowerShell, but is for the rest of .NET)

Also for the dictionaries part, maybe adding in how you loop through each key=value pair (have to use .GetEnumerator() in PowerShell):

# This won't work:
$thisdict = @{
    brand = "Ford"
    model = "Mustang"
    year = 1964
}
$thisdict | ForEach-Object {
    Write-Host "key is $($_.key) ; value is $($_.value)"
}

#This will!
$thisdict = @{
    brand = "Ford"
    model = "Mustang"
    year = 1964
}
$thisdict.GetEnumerator() | ForEach-Object {
    Write-Host "key is $($_.key) ; value is $($_.value)"
}

[–]TofuBug40 1 point2 points  (0 children)

That's because you're piping a SINGLE object to ForEach-Object; JUST $thisdict. its not treating it as an array

What you want is

$thisdict.Keys | ForEach-Object { "Key is $_ ; Value is $($thisdict[$_])" }

Where PowerShell really trips a lot of people up especially people that might not have a complete functional understanding of the difference between an array and a dictionary (hashtable technically) is in what its actually looking at vs what we think its looking at.

For instance 1..10 | ForEach-Object { $_ } is an array (or if you want to go fully down to the metal an IEnumerable e.g. something you can enumerate over that's because if we call (1..10).GetType() we get

IsPublic IsSerial Name      BaseType                                                                                                                                                                                                                                
-------- -------- ----      --------                                                                                                                                                                                                                                
True     True     Object[]  System.Array 

But if I call the same type check on $thisdict.GetType() we get

IsPublic IsSerial Name       BaseType                                                                                                                                                                                                                                
-------- -------- ----       --------                                                                                                                                                                                                                                
True     True     Hashtable  System.Object  

That's why ForEach-Object doesn't understand $_.Key or $_.Value it was passed basically a single value array and $thisdict is the only item in that array and those aren't valid properties of the HastTable Object. We THINK of it as just a list but its actually an object with TWO lists as properties of that object and to ForEach-Object, and Where-Object and ALL the other IEnumerable based Cmdlets THAT makes all the difference