Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting different results using the pipeline with functions

I'm finding that passing objects to functions through the PowerShell pipeline converts them to string objects. If I pass the object as a parameter it keeps its type. To demonstrate:

I have the following PowerShell function which displays a object's type and value:

function TestFunction {
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    Echo $InputObject.GetType().Name
    Echo $InputObject
}

I ran this script to test the function:

[string[]] $Array = "Value 1", "Value 2"

# Result outside of function.
Echo $Array.GetType().Name
Echo $Array
Echo ""

# Calling function with parameter.
TestFunction $Array
Echo ""

# Calling function with pipeline.
$Array | TestFunction

This produces the output:

String[]
Value 1
Value 2

String[]
Value 1
Value 2

String
Value 2

EDIT: How can I use the pipeline to pass an entire array to a function?

like image 313
Hand-E-Food Avatar asked Mar 01 '12 03:03

Hand-E-Food


People also ask

Can pipeline have multiple estimators?

Pipeline can be used to chain multiple estimators into one. This is useful as there is often a fixed sequence of steps in processing the data, for example feature selection, normalization and classification.

Why is implementing a pipeline helpful when you are using cross-validation?

Joint parameter selection: We can perform a grid search over parameters of all estimators in the pipeline. Cross-Validation: Pipelines help to avoid data leakage from the testing data into the trained model during cross-validation.

Which functions creates a pipeline and automatically names each step so that we don't need to specify the names?

'make_pipeline' is a utility function that is a shorthand for constructing pipelines. It takes a variable number of estimates and returns a pipeline by filling the names automatically.

What is pipeline transformation?

The transformation pipeline takes the data read from source data based on the Source Attributes setting and transforms it to a necessary target format with one or multiple operators.


2 Answers

To process multiple items recieved via the pipeline you need a process block in your function:

function Test-Function {
    param (
        [Parameter(ValueFromPipeline=$true)] $Test
    )

    process {
        $Test.GetType().FullName
        $Test
    }
}

[string[]] $Array = "Value 1", "Value 2"
$Array | Test-Function

More info:

  • get-help about_functions http://technet.microsoft.com/en-us/library/dd347712.aspx
  • get-help about_Functions_Advanced http://technet.microsoft.com/en-us/library/dd315326.aspx
like image 135
Andy Arismendi Avatar answered Nov 02 '22 18:11

Andy Arismendi


In addition to having a process block you also need to process each item in the array. It is needed when the array is passed as an argument, not via piping. Consider this:

function Test-Function 
{
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    process
    {
        $InputObject.GetType().Name
    }
}

$Array = "Value 1","Value 2"
Test-Function $array

The result would be String[], which is probably not what you want. The following command will print the type of each item in the array no matter how the argument is passed:

function Test-Function 
{
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    process
    {
        foreach($i in $InputObject)
        {
            $i.GetType().Name
        }
    }
}
like image 22
Shay Levy Avatar answered Nov 02 '22 20:11

Shay Levy