dharmatech
dharmatech

Reputation: 9527

Reverse elements via pipeline

Is there a function that reverses elements passed via pipeline?

E.g.:

PS C:\> 10, 20, 30 | Reverse
30
20
10

Upvotes: 23

Views: 20671

Answers (11)

Maybe
Maybe

Reputation: 1005

One-liners inspired by this answer:

10,20,30 -as 'Collections.Stack' | Write-Verbose -vb
[Collections.Stack](10,20,30) | Write-Verbose -vb
10,20,30 | &{ @($Input) -as 'Collections.Stack' } | Write-Verbose -vb
10,20,30 | &{ [Collections.Stack]@($Input) } | Write-Verbose -vb

The first one looks the nicest, the second one is the shortest, and the last two are for performing the reversal mid-pipeline rather than before the pipeline.

Upvotes: 5

Lamarth
Lamarth

Reputation: 526

You can use Linq.Enumerable.Reverse. Either of the following work:

,(10, 20, 30) | % { [Linq.Enumerable]::Reverse([int[]]$_) }
,([int[]]10, 20, 30) | % { [Linq.Enumerable]::Reverse($_) }

The two challenges are putting the whole array into the pipeline rather than one element at a time (solved by making it an array of arrays with the initial comma) and hitting the type signature of Reverse (solved by the [int[]]).

Upvotes: 1

Busla
Busla

Reputation: 1

10, 20, 30 | Sort-Object @{e={(++$script:i)};d=$true}

same in full syntax:

10, 20, 30 | Sort-Object -Property @{Expression={(++$script:i)}; Descending=$true}

$i shouldn't be local, so I use script scope modifier

() inside {} are needed to return the value of the calculation

Thus, each element acquires a "virtual property" with a serial number. By which it is sorted in reverse order.

Upvotes: 0

jmik
jmik

Reputation: 510

Here's a remarkably compact solution:

function Reverse
{
    [System.Collections.Stack]::new(@($input))
}

Upvotes: 8

Alexey Gusarov
Alexey Gusarov

Reputation: 347

$array = 10,20,30; (($array.Length - 1)..0) | %{ $array[$_] }

Upvotes: 3

David
David

Reputation: 145

10, 20, 30 | Sort-Object -Descending {(++$script:i)}

Upvotes: 11

Michael Moynihan
Michael Moynihan

Reputation: 21

Using $input works for pipe, but not for parameter. Try this:

function Get-ReverseArray {
    Param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeLine = $true)]
        $Array
    )
    begin{
        $build = @()
    }
    process{
        $build += @($Array)
    }
    end{
        [array]::reverse($build)
        $build
    }
}
#set alias to use non-standard verb, not required.. just looks nicer
New-Alias -Name Reverse-Array -Value Get-ReverseArray

Test:

$a = "quick","brown","fox"

#--- these all work 
$a | Reverse-Array
Reverse-Array -Array $a
Reverse-Array $a

#--- Output for each
fox
brown
quick

Upvotes: 2

CodeChops
CodeChops

Reputation: 2056

I realize this doesn't use a pipe, but I found this easier if you just wanted to do this inline, there is a simple way. Just put your values into an array and call the existing Reverse function like this:

$list = 30,20,10
[array]::Reverse($list)
# print the output.
$list

Put that in a PowerShell ISE window and run it the output will be 10, 20, 30.

Again, this is if you just want to do it inline. There is a function that will work for you.

Upvotes: 1

Silviu
Silviu

Reputation: 298

Try:

10, 20, 30 | Sort-Object -Descending

Upvotes: -4

mjolinor
mjolinor

Reputation: 68331

You can cast $input within the function directly to a array, and then reverse that:

function reverse
{ 
 $arr = @($input)
 [array]::reverse($arr)
 $arr
}

Upvotes: 27

dharmatech
dharmatech

Reputation: 9527

Here's one approach:

function Reverse ()
{
    $arr = $input | ForEach-Object { $_ }
    [array]::Reverse($arr)
    return $arr
}

Upvotes: 2

Related Questions