Skip to content

Instantly share code, notes, and snippets.

@urasandesu
Created June 17, 2012 11:50
Show Gist options
  • Save urasandesu/2944313 to your computer and use it in GitHub Desktop.
Save urasandesu/2944313 to your computer and use it in GitHub Desktop.
PowerShell as LINQ
# ----------------------------------------------------------------------------------------------------------
# PowerShell as LINQ
# * When I created this snippet, the blog written by NyaRuRu-san was very helpful.
# I would like to thank him for his article:
# - PowerShell で LINQ - NyaRuRuの日記: http://d.hatena.ne.jp/NyaRuRu/20080112/p2
#
# Change History
# * 2012/06/20 07:23:24: Fix the bug that occurs unintended pipeline breaking.
# The keyword 'return' is reserved, so I use the function name 'run' instead of it.
# * 2012/06/23 22:26:47: Fix the bug that function 'run' doesn't stop enumeration.
# Add function 'flatten' that makes the list flat.
# Add function 'first'. It is shortcut equivalent to 'take 1'.
# ----------------------------------------------------------------------------------------------------------
function __extract__([Collections.IEnumerator]$enum)
{
foreach ($val in $enum)
{
$block = $val -as [scriptblock]
if ($block -eq $null)
{
throw New-Object ArgumentException('The pipeline source object must be a scriptblock.')
}
break
}
$block
}
function repeat([scriptblock]$init)
{
{
$elem = &$init
try
{
while ($true)
{
,$elem
}
}
finally
{
$disp = $elem -as [IDisposable]
if ($disp -ne $null)
{
$disp.Dispose()
}
}
}.GetNewClosure()
}
function take([int]$count)
{
$block = __extract__ $input
{
$count = $count
&$block |
%{
if ($i++ -ge $count)
{
break
}
,$_
}.GetNewClosure()
}.GetNewClosure()
}
function map([scriptblock]$func)
{
$block = __extract__ $input
{
$func = $func
&$block |
%{
,(&$func $_)
}.GetNewClosure()
}.GetNewClosure()
}
function flatten([scriptblock]$func)
{
$block = __extract__ $input
{
$func = $func
&$block |
%{
&$func $_ | %{,$_}
}.GetNewClosure()
}.GetNewClosure()
}
function filter([scriptblock]$func)
{
$block = __extract__ $input
{
$func = $func
&$block |
%{
if (&$func $_)
{
,$_
}
}.GetNewClosure()
}.GetNewClosure()
}
function takeWhile([scriptblock]$func)
{
$block = __extract__ $input
{
$func = $func
&$block |
%{
if (&$func $_)
{
,$_
}
else
{
break
}
}.GetNewClosure()
}.GetNewClosure()
}
function first
{
__extract__ $input | take 1
}
function run
{
do
{
&(__extract__ $input)
} until ($true)
}
# ----------------------------------------------------------------------------------------------------------
# Usage
# ----------------------------------------------------------------------------------------------------------
# dump win.ini
repeat {New-Object IO.StreamReader 'C:\Windows\win.ini'} |
map {param($_1) $_1.ReadLine()} |
takeWhile {param($_1) $_1 -ne $null} |
run
# the sample results are as follows:
#
# ; for 16-bit app support
# [fonts]
# [extensions]
# [mci extensions]
# [files]
# [Mail]
# MAPI=1
# CMCDLLNAME32=mapi32.dll
# CMC=1
# MAPIX=1
# MAPIXVER=1.0.0.1
# OLEMessaging=1
# [MCI Extensions.BAK]
# 3g2=MPEGVideo
# 3gp=MPEGVideo
# 3gp2=MPEGVideo
# 3gpp=MPEGVideo
# aac=MPEGVideo
# adt=MPEGVideo
# adts=MPEGVideo
# m2t=MPEGVideo
# m2ts=MPEGVideo
# m2v=MPEGVideo
# m4a=MPEGVideo
# m4v=MPEGVideo
# mod=MPEGVideo
# mov=MPEGVideo
# mp4=MPEGVideo
# mp4v=MPEGVideo
# mts=MPEGVideo
# ts=MPEGVideo
# tts=MPEGVideo
# get 5 random numbers of one digit.
repeat {New-Object Random} |
map {param($_1) $_1.Next(0, 10)} |
take 5 |
run
# the sample results are as follows:
#
# 4
# 8
# 6
# 8
# 5
# countdown for 10 seconds
$last = 0
repeat {(Get-Date).AddSeconds(10.0)} |
map {param($_1) $_1 - (Get-Date)} |
takeWhile {param($_1) $_1.TotalSeconds -gt 0} |
run |
%{if ($last -ne $_.Seconds){$last = $_.Seconds; $_.Seconds}}
# the sample results are as follows(NOTE: each object will be displayed every second):
#
# 9
# 8
# 7
# 6
# 5
# 4
# 3
# 2
# 1
# 0
# enumerate each first type in each assembly from current AppDomain
{[AppDomain]::CurrentDomain.GetAssemblies()} |
flatten {param($asm) {$asm.GetTypes()} |
first |
map {param($t) $t.AssemblyQualifiedName} |
run} |
run
# the sample results are as follows:
#
# System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# AssemblyStrings, Microsoft.PowerShell.ConsoleHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# FXAssembly, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# System.Management.Automation.ChildItemCmdletProviderIntrinsics, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# Microsoft.PowerShell.Commands.GetWinEventCommand, Microsoft.PowerShell.Commands.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# Microsoft.Contracts.PureAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# FXAssembly, System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
# Microsoft.WSMan.Management.WSManConfigProvider, Microsoft.WSMan.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# System.Transactions.SRDescriptionAttribute, System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# Microsoft.PowerShell.Commands.Internal.Format.FrontEndCommandBase, Microsoft.PowerShell.Commands.Utility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# Microsoft.PowerShell.Commands.CoreCommandBase, Microsoft.PowerShell.Commands.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# Microsoft.PowerShell.Commands.SecurityDescriptorCommandsBase, Microsoft.PowerShell.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
# FXAssembly, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# System.Management.SRDescriptionAttribute, System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
# FXAssembly, System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
# SNINativeMethodWrapper, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# FXAssembly, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
# System.Security.SecurityResources, System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
# System.Xml.Utils.ResDescriptionAttribute, System.Data.SqlXml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment