Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell equivalent of LINQ SelectMany method

I'm writing PowerShell code to get all the local IPv4 addresses, excluding the loopback one. I need something like the LINQ SelectMany method, but I can't figure out how to do this with PS filters. This is the code I have so far, which works using a plain old ArrayList:

function Get-Computer-IP-Address() {     $ipAddresses = New-Object System.Collections.ArrayList      $networkAdaptersWithIp = Get-WmiObject Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null }     foreach ($networkAdapter in $networkAdaptersWithIp)     {         foreach ($ipAddress in $networkAdapter.IPAddress)         {             if ($ipAddress -notlike "127.*" -and $ipAddress -notlike "*::*")             {                 $ipAddresses.Add($ipAddress)             }         }     }      if ($ipAddresses.Length -eq 0)     {         throw "Failed to find any non-loopback IPv4 addresses"     }      return $ipAddresses } 

I'd like to know if there's a cleaner way to do it, with less code.

like image 625
EMP Avatar asked Mar 09 '11 04:03

EMP


2 Answers

Just to answer the question from the subject "PowerShell equivalent of LINQ SelectMany method":

collection.SelectMany(el => el.GetChildren()) // SelectMany in C# 

is equivalent to

$collection | % { $_ }                    # SelectMany in PowerShell for array of arrays $collection | % { $_.GetChildren() }      # SelectMany in PowerShell for complex object 

Example

$a = (1,2,3),('X','F'),'u','y' $a.Length                # output is 4 ($a | % { $_ }).Length   # output is 7 

Another example

$dirs = dir -dir c: $childFiles = $dirs | % { $_.GetFiles() } $dirs.Length          # output is 6 $childFiles.Length    # output is 119 
like image 150
Ivan Akcheurov Avatar answered Sep 21 '22 21:09

Ivan Akcheurov


You can do it if you combine Foreach-Object and Where-Object like this:

$ipaddresses = @(   Get-WmiObject Win32_NetworkAdapterConfiguration |    ? { $_.IPAddress -ne $null } |   % { $_.IPAddress } |   ? { $_ -notlike "127.*" -and $_ -notlike "*::*" }) 

Note the @(...). This causes that if result of the pipeline inside is nothing, empty array is assigned to $ipaddresses.

like image 32
stej Avatar answered Sep 21 '22 21:09

stej