What is the Linq.First equivalent in PowerShell?
The snippet below detects from a list of files which of them is a Directory on Ftp
as C# it will be like below
var files = new List<string>(){"App_Data", "bin", "Content"};
var line = "drwxr-xr-x 1 ftp ftp 0 Mar 18 22:41 App_Data"
var dir = files.First(开发者_JAVA技巧x => line.EndsWith(x));
How I can transalte the last line in PowerShell ?
Something like this...
$files = @("App_Data", "bin", "Content")
$line = "drwxr-xr-x 1 ftp ftp 0 Mar 18 22:41 App_Data"
$dir = $files | Where { $line.EndsWith($_) } | Select -First 1
These versions of the last line would all accomplish the same:
$dir = @($files | Where { $line.EndsWith($_) })[0]
$dir = $files | Where { $line.EndsWith($_) } | Select -index 0
$dir = $files | Where { $line.EndsWith($_) } | Select -First 1
It was pointed out that the above is not exactly equivalent in behavior to Linq.First because Linq.First throws exceptions in two cases:
- Throws ArgumentNullException when source or predicate is null.
- Throws InvalidOperationException when source sequence is empty or no element satisfies the condition in predicate.
If you wanted that behavior exactly, you'd need some extra guard code.
as Robert Groves said, Select-Object -First Occurence do the tricks, you can also use -Last Occurence.
by the way, like any other static .Net method you can use linq in powershell.
[Linq.Enumerable]::First($list)
[Linq.Enumerable]::Distinct($list)
[Linq.Enumerable]::Where($list, [Func[int,bool]]{ param($item) $item -gt 1 })
Doug Finke produced a great video ( only 7 mins ) about converting C# to Powershell http://dougfinke.com/video/CSharpToPowerShell.html
Roberts example is very good indeed, though comma delimiting will implicitly be treated as an array
the shortest way of doing it would be to put it all into a single pipeline :
$dir = "App_Data", "bin", "Content" | % { if("drwxr-xr-x 1 ftp ftp 0 Mar 18 22:41 App_Data".EndsWith($_)) { $_ } } | select -first 1
There is a native way to do this using the Powershell Array's Where Function by passing in a WhereOperatorSelectionMode
like this:
(1..9).Where({ $_ -gt 3}, "First") # 4
You can also use the mode straight from the enum as well:
$mode = [System.Management.Automation.WhereOperatorSelectionMode]::First
(1..9).Where({ $_ -gt 3}, $mode) # 4
Using any of the values from the WhereOperatorSelectionMode
enum
Name | Val | Description |
---|---|---|
Default |
0 |
Return all items |
First |
1 |
Return the first item |
Last |
2 |
Return the last item |
SkipUntil |
3 |
Skip items until condition is true |
Until |
4 |
Return all items until condition is true |
Split |
5 |
Return an array of two elements |
See Also: Checking Out The Where and ForEach Operators in PowerShell V4
This is a really simple implementation for First
:
function First($collection)
{
foreach ($item in $collection)
{
return $item
}
return $null
}
Instead of returning $null
, you could throw an InvalidOperationException
exception.
精彩评论