Skip to content

Instantly share code, notes, and snippets.

@neuecc
Last active August 29, 2015 14:05
Show Gist options
  • Save neuecc/80ec2caa0e9653bdbc35 to your computer and use it in GitHub Desktop.
Save neuecc/80ec2caa0e9653bdbc35 to your computer and use it in GitHub Desktop.
Zip.ps1
# emptyの時にnull返しちゃうけど要素の型取れないしshoganai
# enumeratorをDisposeしない(ちゃんとしよふ)
$first = @(1, 2,3)
$second = @(5, 6,7, 10)
$e1 = $first.GetEnumerator()
$e2 = $second.GetEnumerator()
$list = $null
while ($e1.MoveNext() -and $e2.MoveNext()) {
if($list -eq $null)
{
$keyType = $e1.Current.GetType()
$valueType = $e2.Current.GetType()
$list = New-Object "System.Collections.Generic.List[System.Tuple[$keyType, $valueType]]"
}
$list.Add($(New-Object "System.Tuple[[$keyType],[$valueType]]" ($e1.Current, $e2.Current)));
}
Write-Host $list
@neuecc
Copy link
Author

neuecc commented Aug 19, 2014

$first.GetType()がobject[]なときのかなしみ。
$first.GetType().GetElementType()が当然objectなかなしみ。

@neuecc
Copy link
Author

neuecc commented Aug 19, 2014

$first = @(1, 2,3)
$second = @(5, 6,7, 10)

$e1 = $first.GetEnumerator()
$e2 = $second.GetEnumerator()

$list = $null
try
{
    while ($e1.MoveNext() -and $e2.MoveNext())
    {
        if($list -eq $null)
        {
            $keyType = $e1.Current.GetType()
            $valueType = $e2.Current.GetType()
            $list = New-Object "System.Collections.Generic.List[System.Tuple[$keyType, $valueType]]"
        }
        $list.Add($(New-Object "System.Tuple[[$keyType],[$valueType]]" ($e1.Current, $e2.Current)));
    }
}
finally
{
    $d1 = $e1 -as [IDisposable]
    $d2 = $e1 -as [IDisposable]
    if($d1 -ne $null) { $d1.Dispose() }
    if($d2 -ne $null) { $d2.Dispose() }
}

# empty listを返すほうが好ましいんですけどねー、とはいえここでobject[0]を返されても困る?そうでもない?ふつう?
Write-Host $list

@guitarrapc
Copy link

んー、なんとなくできたかも。

function New-ZipPairs
{
    [CmdletBinding()]
    param
    (
        [parameter(
            Mandatory = 0,
            Position = 0,
            ValueFromPipelineByPropertyName = 1)]
        $first,

        [parameter(
            Mandatory = 0,
            Position = 1,
            ValueFromPipelineByPropertyName = 1)]
        $second
    )

    process
    {
        if ([string]::IsNullOrWhiteSpace($first)){ break }        
        if ([string]::IsNullOrWhiteSpace($second)){ break }

        # Get Type
        $keyType = GetType -Element $first
        $valueType = GetType -Element $second

        # Initialize List
        $list = New-Object "System.Collections.Generic.List[System.Tuple[$keyType, $valueType]]"

        # Get Typed element
        $e1 = @(ToListEx -InputElement $first -type $keyType).GetEnumerator()
        $e2 = @(ToListEx -InputElement $second -type $valueType).GetEnumerator()

        try
        {
            while ($e1.MoveNext() -and $e2.MoveNext())
            {
                $e1Current = TakeTypedElement -InputElement $e1.Current -type $keyType
                $e2Current = TakeTypedElement -InputElement $e2.Current -type $valueType
                $list.Add($(New-Object "System.Tuple[[$keyType],[$valueType]]" ($e1Current, $e2Current)));
            }
        }
        finally
        {
            $d1 = $e1 -as [IDisposable]
            $d2 = $e1 -as [IDisposable]
            if($d1 -ne $null) { $d1.Dispose() }
            if($d2 -ne $null) { $d2.Dispose() }
        }
    }

    end
    {
        return $list
    }

    begin
    {
        function GetType ($Element)
        {
            $e = @($Element).GetEnumerator()
            $e.MoveNext() > $null
            $e.Current.GetType().FullName
        }

        function TakeTypedElement ($InputElement, $type)
        {
            @($InputElement) | where {$_.GetType().FullName -eq $type}
        }

        function ToListEx ($InputElement, $type)
        {
            $list = New-Object "System.Collections.Generic.List[$type]"
            @($InputElement) | where {$_.GetType().FullName -eq $type} | %{$list.Add($_)}
            return @($list)
        }
    }
}

@guitarrapc
Copy link

$first = 1, 2,3
$second = 5, 6,7, 10
New-ZipPairs -first $first -second $second

$first = ps
$second = ls
New-ZipPairs -first $first -second $second

$first = 1, 2, 3, 4
$second = "hoge", "moge", "fuga", "piyo"
New-ZipPairs -first $first -second $second

$first = 1
$second = "hoge", "fuga"
New-ZipPairs -first $first -second $second

$first = ""
$second = "hoge"
New-ZipPairs -first $first -second $second

@neuecc
Copy link
Author

neuecc commented Aug 20, 2014

が分からなくてもう全行解説してもらうしかないと思いました……。

@guitarrapc
Copy link

なんか、これで十分だったお。

function New-Zip
{
    [CmdletBinding()]
    param
    (
        [parameter(
            Mandatory = 0,
            Position = 0,
            ValueFromPipeline = 1,
            ValueFromPipelineByPropertyName = 1)]
        [PSObject[]]
        $first,

        [parameter(
            Mandatory = 0,
            Position = 1,
            ValueFromPipelineByPropertyName = 1)]
        [PSObject[]]
        $second,

        [parameter(
            Mandatory = 0,
            Position = 2,
            ValueFromPipelineByPropertyName = 1)]
        [scriptBlock]
        $resultSelector
    )

    process
    {
        if ([string]::IsNullOrWhiteSpace($first)){ break }        
        if ([string]::IsNullOrWhiteSpace($second)){ break }

        try
        {
            $e1 = @($first).GetEnumerator()

            while ($e1.MoveNext() -and $e2.MoveNext())
            {
                if ($PSBoundParameters.ContainsKey('resultSelector'))
                {
                    $first = $e1.Current
                    $second = $e2.Current
                    $context = $resultselector.InvokeWithContext(
                        $null,
                        ($psvariable),
                        {
                            (New-Object System.Management.Automation.PSVariable ("first", $first)),
                            (New-Object System.Management.Automation.PSVariable ("second", $second))
                        }
                    )
                    $context
                }
                else
                {
                    $tuple = New-Object 'System.Tuple[PSObject, PSObject]' ($e1.Current, $e2.current)
                    $tuple
                }
            }
        }
        finally
        {
            if(($d1 = $e1 -as [IDisposable]) -ne $null) { $d1.Dispose() }
            if(($d2 = $e2 -as [IDisposable]) -ne $null) { $d2.Dispose() }
            if(($d3 = $psvariable -as [IDisposable]) -ne $null) {$d3.Dispose() }
            if(($d4 = $context -as [IDisposable]) -ne $null) {$d4.Dispose() }
            if(($d5 = $tuple -as [IDisposable]) -ne $null) {$d5.Dispose() }
        }
    }

    begin
    {
        $e2 = @($second).GetEnumerator()
        $psvariable = New-Object 'System.Collections.Generic.List[PSVariable]]'
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment